我正在编写一个bash脚本,该脚本使用其他输入为命令构建一组复杂的参数。到目前为止,脚本使用此技术完美运行:
whatIwant="command "$filename-with-spaces-maybe" -opt1 "$some_words" -opt2 $a_number -opt3 "$a_file_reference" -opt4 "$several_sentences" "
eval $whatIwant
虽然它可以工作,但我对使用eval
持谨慎态度,因为错误的文件名可能会造成损害。我希望能够跳过分配变量然后对其进行评估,而只是将命令放在行首,并让所有参数都由我之前在脚本中构建的适当变量设置。
但是,当我尝试此操作时,文件名似乎并未被视为单个变量,而是作为多个参数传递给命令。我已经尝试了几种形式的双重转义,但未能找到正确评估的东西。这很令人沮丧,因为当我回显我构建命令的变量时,它会完美地复制并粘贴到命令行并执行我想要的操作。
在 bash 脚本中执行此操作的最佳实践是什么?
其实就是这么简单:
your_command "$filename_with_spaces_maybe" -opt1 "$some_words" -opt2 "$a_number" -opt3 "$a_file_reference" -opt4 "$several_sentences"
也就是说:
- 将每个参数扩展(变量名称替换为其值(放在双引号中 - 即使您认为该值只是数字。
- 不要为任何类型的
eval
或任务等而烦恼。
唯一需要的引号是语法,而不是文字 - "嵌套"或"转义"引号是没有句法含义的文字字符,因此它们对解析没有影响(没有额外的解析步骤,如eval
生成,这确实是可以避免的不好的做法(,只是向实际运行的命令添加额外的不需要的内容。
对于您认为出于其他原因需要在变量中存储命令的情况(仅有条件地添加参数,或者能够重用它(,请参阅 BashFAQ #50。
如果你还不相信eval
是个坏主意,你会想阅读BashFAQ #48。
关于报价的Wooledge页面通常是这个问题的绝佳资源。