问题描述
我正在制作一个 bash 脚本,它将打印复杂的参数并将其传递给另一个外部程序.
I am making a bash script that will print and pass complex arguments to another external program.
./script -m root@hostname,root@hostname -o -q -- 'uptime ; uname -a'
如何打印原始参数:
-m root@hostname,root@hostname -o -q -- 'uptime ; uname -a'
使用 $@
和 $*
删除 uptime 周围的单引号;uname -a
这可能会导致不希望的结果.我的脚本不需要解析每个参数.我只需要打印/记录参数字符串并将它们完全按照给出的方式传递给另一个程序.
Using $@
and $*
removes the single quotes around uptime ; uname -a
which could cause undesired results. My script does not need to parse each argument. I just need to print / log the argument string and pass them to another program exactly how they are given.
我知道我可以使用诸如 "'uptime ; uname -a'"
之类的东西来转义引号,但我不能保证用户会这样做.
I know I can escape the quotes with something like "'uptime ; uname -a'"
but I cannot guarantee the user will do that.
推荐答案
在将参数传递给脚本之前将删除引号,因此保留它们为时已晚.您可以做的是在将参数传递给内部命令时保留它们的效果,并重建参数的等效引用/转义版本以进行打印.
The quotes are removed before the arguments are passed to your script, so it's too late to preserve them. What you can do is preserve their effect when passing the arguments to the inner command, and reconstruct an equivalent quoted/escaped version of the arguments for printing.
为了将参数传递给内部命令 "$@"
-- 使用双引号,$@ 保留原始分词符,这意味着内部命令接收完全相同的参数列出您的脚本所做的.
For passing the arguments to the inner command "$@"
-- with the double-quotes, $@ preserves the original word breaks, meaning that the inner command receives exactly the same argument list that your script did.
对于打印,您可以在 bash 的 printf 命令中使用 %q 格式来重建引用.请注意,这不会总是重建原始引用,但会构造一个 等效 引用/转义字符串.例如,如果您传递了参数 'uptime ;uname -a'
它可能会打印 uptime ; uname -a
或 "uptime ;uname -a"
或任何其他等效项(有关类似示例,请参阅 @William Pursell 的回答).
For printing, you can use the %q format in bash's printf command to reconstruct the quoting. Note that this won't always reconstruct the original quoting, but will construct an equivalent quoted/escaped string. For example, if you passed the argument 'uptime ; uname -a'
it might print uptime ; uname -a
or "uptime ; uname -a"
or any other equivalent (see @William Pursell's answer for similar examples).
以下是使用这些的示例:
Here's an example of using these:
printf "Running command:"
printf " %q" innercmd "$@" # note the space before %q -- this inserts spaces between arguments
printf "
"
innercmd "$@"
如果您有 bash 4.4 或更高版本,您可以在参数扩展上使用 @Q
修饰符来添加引用.这往往更喜欢使用单引号(与 printf %q
对转义的偏好相反).您可以将其与 $*
结合使用以获得合理的结果:
If you have bash version 4.4 or later, you can use the @Q
modifier on parameter expansions to add quoting. This tends to prefer using single-quotes (as opposed to printf %q
's preference for escapes). You can combine this with $*
to get a reasonable result:
echo "Running command: innercmd ${*@Q}"
innercmd "$@"
请注意,$*
将所有参数混合成一个字符串,它们之间有空格,这通常没有用,但在这种情况下,每个参数都单独引用,因此结果实际上是您(可能)想要.(好吧,除非你改变了 IFS
,在这种情况下,参数之间的空格"将是 $IFS
的第一个字符,这可能不是 成为你想要的.)
Note that $*
mashes all arguments together into a single string with whitespace between them, which is normally not useful, but in this case each argument is individually quoted so the result is actually what you (probably) want. (Well, unless you changed IFS
, in which case the "whitespace" between arguments will be the first character of $IFS
, which may not be what you want.)
这篇关于在 bash 参数中保留引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!