I have a complex qsub command to run remotely.
PROJECT_NAME_TEXT="TEST PROJECT"
PACK_ORGANIZATION="--source-organization \'MY, ORGANIZATION\'"
CONTACT_NAME="--contact-name \'Tom Riddle\'"
PROJECT_NAME_PACK="--project-name \"${PROJECT_NAME_TEXT}\""
INPUTARGS="${PACK_ORGANIZATION} ${CONTACT_NAME} ${PROJECT_NAME_PACK}"
ssh mycluster "qsub -v argv="$INPUTARGS" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script"
The problem is the remote cluster doesn't recognise the qsub command, it always showing incorrect qsub command or simply alway queued on cluster because of input args are wrong.
It must be the escaping problem, my question is how to escape the command above properly ?
Try doing this using a here-doc : you have a quote conflict (nested double quotes that is an error):
As you can see, here-docs are really helpful for inputs with quotes.
See
man bash | less +/'Here Documents'
Edit
from your comments :
You can ignore this warning with
(try the
-t
switch forssh
if needed)If you have
I think you have a copy paste problem. Try to remove extra spaces on all end lines
it seems related to your
EOF
problem.What does this means ?
$argv
is not a pre-defined variable inbash
. If you need to list command line arguments, use the pre-defined variable$@
Last thing : ensure you are using
bash
Your problem is not the length, but the nesting of your quotes - in this line, you are trying to use
"
inside"
, which won't work:Bash will see this as
"qsub -v argv="
followed by$INPUTARGS
(not quoted), followed by" -l walltime=10:00:00 -l vmem=8GB -l nodes=1:ppn=4 /myscript_path/run.script"
.It's possible that backslash-escaping those inner quotes will have the desired effect, but nesting quotes in bash can get rather confusing. What I often try to do is add an
echo
at the beginning of the command, to show how the various stages of expansion pan out. e.g.The described escaping problem consists in the requirement to preserve final quotes around arguments after two evaluation processes, i. e. after two evaluations we should see something like:
This can be achieved codewise by first putting each argument in a separate variable and then enclosing the argument with single quotes while making sure that possible single quotes inside the argument string get "escaped" with
'\''
(in fact, the argument will be split up into separate strings but, when used, the split-up argument will automatically get re-concatenated by the string evaluation mechanism of UNIX (POSIX?) shells). And this procedure has to be repeated three times.For further information please see:
Thanks for all the answers, however their methods will not work on my case. I have to answer this by myself since this problem is pretty complex, I got the clue from existing solutions in stackoverflow.
There are 2 problems must be solved in my case.
Pass local program's parameters to the remote cluster. Here-doc solution doesn't work in this case.
Run qsub on remote cluster with the a long variable as arguments that contain quote symbol.
Problem 1.
Firstly, I have to introduce my script that runs on local machine takes parameters like this:
The real parameter is far more longer than above, so all the parameter must be sent to remote. They are sent in file like this:
My solution is sort of compromising. But in this way the remote cluster can run script with arguments contain quote symbol. If you don't put all your variable (as parameters) in a file and transfer it to remote cluster, no matter how you pass them into variable, the quote symbol will be removed.
Problem 2.
Check how the qsub runs on remote cluster.
And in the my.script: