问题
I am writing a bash script that uses other inputs to build a set of complicated arguments for a command. So far, the script runs perfectly with this technique:
whatIwant="command \"$filename-with-spaces-maybe\" -opt1 \"$some_words\" -opt2 $a_number -opt3 \"$a_file_reference\" -opt4 \"$several_sentences\" "
eval $whatIwant
Although it works, I am wary of using eval
because of the risk of a bad filename doing damage. I would like to be able to skip assigning the variable and then eval'ing it, in favor of just putting the command at the beginning of the line and having all the arguments be set by the appropriate variables I have built previously in the script.
When I try this, however, the filenames don't seem to be treated as single variables, and instead are passed to the command as multiple arguments. I have tried several forms of double escaping but haven't managed to find something that is correctly evaluated. It's frustrating because when I echo back my variable into which I build the command, it copies and pastes perfectly to the command line and does what I want.
What is the best practice for doing this in a bash script?
回答1:
It's really this simple:
your_command "$filename_with_spaces_maybe" -opt1 "$some_words" -opt2 "$a_number" -opt3 "$a_file_reference" -opt4 "$several_sentences"
That is to say:
- Put every parameter expansion (where a variable name is replaced with its value) in double quotes -- even if you think the value will only be numeric.
- Don't bother with any kind of
eval
, or assignment, etc.
The only quotes required are syntactic, not literal -- "nested" or "escaped" quotes are literal characters without syntactic meaning, so they have no effect on parsing (without an additional parse step, as generated by eval
, which is indeed bad practice when at all avoidable), and just add extra unwanted content to the command actually being run.
For cases when you think you need to store a command in a variable for other reasons (to add arguments only conditionally, or to be able to reuse it), see BashFAQ #50.
If you weren't already convinced that eval
is a Bad Idea, you'd want to read BashFAQ #48.
The Wooledge page on Quotes is an excellent resource for this question in general.
来源:https://stackoverflow.com/questions/44981904/handling-quoting-and-escaped-spaces-in-bash-command-arguments