我正在制作一个bash脚本,它将打印并将复杂的参数传递给另一个外部程序.
./script -m root@hostname,root@hostname -o -q -- 'uptime ; uname -a'
Run Code Online (Sandbox Code Playgroud)
如何打印原始参数:
-m root@hostname,root@hostname -o -q -- 'uptime ; uname -a'
Run Code Online (Sandbox Code Playgroud)
使用$@和$*删除uptime ; uname -a可能导致意外结果的单引号.我的脚本不需要解析每个参数.我只需要打印/记录参数字符串并将它们传递给另一个程序,确切地说它们是如何给出的.
我知道我可以用类似的东西来逃避引号, "'uptime ; uname -a'"但我无法保证用户会这样做.
Gor*_*son 16
在将参数传递给脚本之前删除引号,因此保留它们为时已晚.您可以做的是在将参数传递给内部命令时保留其效果,并重新构建用于打印的参数的等效引用/转义版本.
为了将参数传递给内部命令"$@"- 使用双引号,$ @保留原始单词中断,这意味着内部命令接收与脚本完全相同的参数列表.
对于打印,您可以在bash的printf命令中使用%q格式来重建引用.请注意,这不会始终重建原始引用,但会构造等效的引用/转义字符串.例如,如果你传递的参数'uptime ; uname -a'可能打印uptime\ \;\ uname\ -a或"uptime ; uname -a"或任何其他等效(见@William Pursell对类似的例子回答).
以下是使用这些的示例:
printf "Running command:"
printf " %q" innercmd "$@" # note the space before %q -- this inserts spaces between arguments
printf "\n"
innercmd "$@"
Run Code Online (Sandbox Code Playgroud)
小智 9
使用 ${@@Q} 获得简单的解决方案。要测试它,请将以下行放入脚本bigQ中。
#!/bin/bash
line="${@@Q}"
echo $line
Run Code Online (Sandbox Code Playgroud)
跑步:
./bigQ 1 a "4 5" b="6 7 8"
'1' 'a' '4 5' 'b=6 7 8'
Run Code Online (Sandbox Code Playgroud)
如果用户调用您的命令为:
./script 'foo'
Run Code Online (Sandbox Code Playgroud)
给脚本的第一个参数是foo不带引号的字符串。您的脚本无法区分它和它可以foo作为参数获取的任何其他方法(例如./script $(echo foo)or./script foo或./script "foo"or ./script \f\o""''""o)。