我遇到过几次的情况:我有一个 shell 函数,它进行一些设置,然后调用或多或少的任意命令,如下所示:
setup_and_run() {
some_setup_commands
"$@"
}
我想更改此函数以编写一个脚本文件,我可以在执行相同设置后使用它来重新运行命令。我可以执行以下操作,当命令中没有带空格或其他奇怪内容的参数时,该操作有效:
setup_and_run() {
some_setup_commands
cat >>rerun.sh <<EOF
some_setup_commands
$@
EOF
"$@"
}
有没有一种标准的方法来改变它,以便脚本可以用正确的引用来编写,一般来说,即使某些参数有空格或其他特殊字符?
例如,使用 的第二个定义setup_and_run
,如果我运行
$ setup_and_run ls "my cat's \"password\""
my cat's "password"
然后rerun.sh
将包含
some_setup_commands
ls my cat's "password"
而我希望它包含类似
some_setup_commands
ls "my cat's \"password\""
或者
some_setup_commands
ls my\ cat\'s\ \"password\"
或类似的东西。
在紧要关头,我可以将它外包给 Python 之类的东西shlex.quote()
,但我正在寻找可以在 shell 本身中完成的东西,或者至少使用更轻量级的标准 UNIX 工具。
在 bash、ksh93 和 zsh 中,您可以
%q
对printf
内置的.在 bash 中,您可以使用 将
printf -v
输出写入变量而不是标准输出。在 zsh 中,有一个不同的方法是
q
参数扩展标志,然后用j: :
空格连接数组元素。在普通的 sh 中,它更难。引用一个单词的可靠方法是在它周围加上单引号,并将其中的每个单引号替换为
'\''
. 正确地进行替换并不是很容易,涉及对 sed 的外部调用或循环。