2

I have to use a bash script (I'm not familiar with bash) for submitting a HPC job. The job-submission script template sets the command and options and then combines them in the end:

input="file_name"
name="simulation1"

application=my_app
options="in=$input.h5 out=$name.h5 param1=foo"

cmd="$application $options"

this all works okay, i.e. eval $cmd executes

my_app in=$input.h5 out=$name.h5 param1=foo

until I need the character '>' in the options. In particular, I want to add the option absrad="mass>1?H:0", but if I simply set

options="in=$input.h5 out=$name.h5 param1=foo absrad=mass>1?H:0"

then bash truncates that at the '>', so that eval $cmd executes

my_app in=$input.h5 out=$name.h5 param1=foo absrad=mass

instead. How to fix that such that eval $cmd executes

my_app in=$input.h5 out=$name.h5 param1=foo absrad="mass>1?H:0"

EDIT. Note that this is similar to, but not a duplicate of this post, where a single-quoted argument is the problem. Moreover, the answers there only consider solutions using an array for the options. I would like alternatives w/o array.

Community
  • 1
  • 1
Walter
  • 44,150
  • 20
  • 113
  • 196
  • doesn't bash have a standard escape character? like "\>" – Wes Apr 28 '17 at 18:42
  • or single quotes might also work – Wes Apr 28 '17 at 18:43
  • Is your command called like `$cmd` or `"$cmd"` because the latter should work. – Olli K Apr 28 '17 at 18:47
  • Does `\>` fix the issue? Do you have `1?H:0` in the directory after you ran the script? – Arkadiusz Drabczyk Apr 28 '17 at 18:48
  • 1
    FYI - `eval` is not truncating per se, but scanning the string and performing variable substitution and when it gets to the `'>'` it sees the redirection character and will create a file called `'1?H:0'`. Then it passes the line to the shell for execution. Another reason to avoid using eval which can be dangerous if the variables it is operating on can be manipulated. – Gary_W Apr 28 '17 at 18:53
  • I should have said `eval` can be dangerous if the variables it is operating on can be manipulated to contain commands. Consider this: param1="ls -l";options=$param1;eval $options. Now imagine something more devious then a `ls -l` as a command. I found this post with alternatives but do a little searching, you'll find safer ways: http://stackoverflow.com/questions/17529220/why-should-eval-be-avoided-in-bash-and-what-should-i-use-instead – Gary_W Apr 28 '17 at 19:04
  • @Barmar It's not really an (exact) dupe and the answers provided (one by you) are rather narrow. – Walter Apr 29 '17 at 09:11
  • They don't have to be "exact" duplicates, as long as the answers show how to solve the same problem. It's very rare that questions exactly duplicate each other, but they're the same idea.\ – Barmar Apr 29 '17 at 09:16
  • 1
    By closing this question you deprive the chance for an alternative (to arrays) answer. – Walter Apr 29 '17 at 11:50

1 Answers1

1

You could always use an array for options:

declare -a options=("in=$input.h5" "out=$name.h5" "param1=foo" "absrad=\"mass>1?H:0\"");
declare -a cmd=(my_app "${options[@]}");

Then when you want to expand cmd the following should give you the correct expansion:

"${cmd[@]}"

Additionally, this gets rid of the need to use eval, which I tend to avoid whenever possible.

Jeffrey Cash
  • 1,023
  • 6
  • 12