Search code examples
bashquoting

Double quotes is not helping me to pass a string argument with spaces


I'm writing some bash scripts to make easier submitting jobs to a compute cluster using the oar syntax, and for the option I need they say that they use SQL syntax (option -p).

For some context, here is the command I am using:

oarsub -q production -p "GPU = 'GTX 980'" -l "nodes=1,walltime=00:05" -I

Where I want to be able to change the GTX 980 and 00:05 with inputs given by the user.

I have had success with just taking time as an input and leaving the GPU fixed:

oarsub -q production -p "GPU = 'GTX 980'" -l "nodes=1,walltime=$1" -I

I have already tried using double quotes as stated on these answers 1, 2, 3. But it seems like parameter expansion keeps happening with:

echo "$2"
oarsub -q production -p "GPU = "$2"" -l "nodes=1,walltime=$1" -I
manuel@machine$: bash job_script.sh 00:05 'GTX 980'
GTX 980
...
/!\ You asked for an Interactive job SO I will ignore arguments: 980 ; Is your syntax right?
...
[ADMISSION RULE] Job properties : (GPU = GTX) AND maintenance = 'NO'
Generate a job key...
Bad resource request (ERROR:  column "gtx" does not exist
LINE 4: ...alltime >= 300 OR max_walltime <= 0)) AND ((GPU = GTX) AND m...

Where it seems like it is not taking the whole 'GTX 980' as a complete string on, but instead is splitting them into 'GTX' and '980', because of the: /!\ You asked for an Interactive job SO I will ignore arguments: 980 ; Is your syntax right? warning.

Is is a way I could pass the GPU name as a bash input argument to the command? Or it might be some problem between how bash formats and passes the input to oarsub?


Solution

  • Oguz ismail's advise in this comment is perfectly correct. However, if the value of the other positional parameter, $1, might also contain some spaces, you should quote it as well. And since these quotes do no harm otherwise, quote it in any case:

    oarsub -q production -p "GPU = '$2'" -l "nodes=1,walltime='$1'" -I
    

    Please note: The calling shell expands this to something like

    oarsub -q production -p GPU = 'blah blah' -l nodes=1,walltime='foo bar' -I
    

    where GPU = 'blah blah' and nodes=1,walltime='foo bar' are treated as single words that are passed as single arguments to oarsub as it should be.

    Apart from that, in general, it is not necessary to hierarchically nest the quoted parts of a command line: You may simply concatenate them, basically like so:

    oarsub -q production -p 'GPU = '\'"$2"\' -l 'nodes=1,walltime='\'"$1"\' -I
    

    In this way you have full control of what parts are expanded and what parts are subject to word splitting. However, this is not necessary in your case. So you can just follow the suggestion above, which are by far easier to read and therefore clearer.