问题描述
这是我要做的事情的精简示例。
#!/usr/bin/env bash
set -x
echo "$@"
用
调用bash script -vv --foo='bar baz'
收益
+ echo -vv 'foo=bar baz'
-vv foo=bar baz
请注意,+行(即调试行)将单引号放在整个foo = bar baz周围。我需要它通过
foo='bar baz'
不是
'foo=bar baz'
我尝试了几次迭代均无济于事。 有办法让它通过前者吗?
解决方法
set -x
不会更改参数中的引号:foo='bar baz'
和'foo=bar baz'
是编写同一字符串的两种不同方式。传递这些参数的任何程序都将在其argv数组中的相关位置获得C字符串"foo=bar baz"
(那些双引号是C语法,而不是文字内容)。请注意,该字符串中的任何地方都没有'
。
这是正确的,因为所有POSIX shell(bash是成员的一个类)均基于每个字符对报价进行评估;句法引号在实际执行之前被删除,因此仅保留文字数据。
在foo='bar baz'
中,您将foo=
放在无引号的上下文中,将bar baz
放在单引号的上下文中,并将它们连接在一起成为一个字符串。
在'foo=bar baz'
中,shell的调试输出向您显示了包含该操作结果的单个字符串。
这些字符串是相同的;它们恰好是使用不同的语法来描述的。因此,由于这两种表示形式之间的区别而导致的任何错误都是不可能的,因为它们导致传递给调用程序的值是完全相同的。 被调用程序无法确定使用了哪个程序,因此无法根据区别来更改其行为。因此,基于此区别的错误是不可能的。