如何通过cli参数将foo ='bar baz'传递给命令

问题描述

这是我要做的事情的精简示例。

#!/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的调试输出向您显示了包含该操作结果的单个字符串。

这些字符串是相同的;它们恰好是使用不同的语法来描述的。因此,由于这两种表示形式之间的区别而导致的任何错误都是不可能的,因为它们导致传递给调用程序的值是完全相同的。 被调用程序无法确定使用了哪个程序,因此无法根据区别来更改其行为。因此,基于此区别的错误是不可能的。