1
$ foo='A="1 2" B=3' sh -c 'ruby -e "p ARGV" $foo'
["A=\"1", "2\"", "B=3"]

我该如何["A=1 2", "B=3"]取而代之?

我知道:

sh -c 'ruby -e "p ARGV" A="1 2" B=3'
["A=1 2", "B=3"]

但该变量foo是必需的,因为我真正的问题是在 Jenkins 作业中的“shell 执行过程”中。

编辑:在同一个外壳中使用一个数组

$ foo=(A="1 2" B=3) && ruby -e "p ARGV" $foo
["A=1 2", "B=3"]

但是,数组不能作为环境变量传播...

$ foo=(A="1 2" B=3) sh -c 'ruby -e "p ARGV" $foo'
[]
4

5 回答 5

3

您需要逃离空间以弥合由于缺乏正确引用而造成的鸿沟。

foo='A="1\ 2" B=3' sh -c 'ruby -e "p ARGV" $foo'

这基本上是“不要那样做”问题的变体。http://mywiki.wooledge.org/BashFAQ/050

于 2012-12-26T09:20:11.103 回答
2

我们在 Jenkins 上遇到了这个确切的问题。IE

./ourScript.py "${args}"

尽管有引号,但 args 在空间上被打破了。

我们用

eval "./ourScript.py '${args}'"

于 2016-06-03T12:38:55.200 回答
1

我的理解是,您想向 ruby​​(A=1 2B=3)发送 2 个附加参数,但在单个变量(foo)中。这并不简单,因为第一个参数中的空格将用于子shell 的分词。一个解决方案是告诉 subshel​​l 使用另一个字符进行分词(我正在使用_波纹管)。所以你的脚本变成:

foo="A=1 2_B=3" sh -c 'IFS=_; ruby -e "p ARGV" $foo'

如果您想_在参数中保留一个可能的字符,您可以使用换行符进行分词,但它变得不那么可读:

foo="A=1 2
B=3" sh -c 'IFS="
"; ruby -e "p ARGV" $foo'
于 2012-12-26T17:03:39.683 回答
0

正如我在问题答案的评论中提到的那样,程序采用这些参数(A 和 B)是make. 所以,我决定扩展$(foo)一个配方并调用 submake。因为make按原样扩展变量。

前:

$ foo='A="1 2" B=3' sh -c 'make $foo'

后:

$ foo='A="1 2" B=3' sh -c 'make wrapper'

生成文件:

wrapper:
    make $(foo)

这不是我问题的确切答案,而是我选择的解决方案。

于 2012-12-27T12:57:32.187 回答
0
sh -s 'A=1 2' B=3 <<\EOF
export "$@"
python3 -c 'import os; print("\n".join(os.environ[x] for x in ["A", "B"]))' "$foo"
EOF

这需要您/bin/sh支持export未发布的 POSIX-2008 TC1 指定的声明命令行为。

翻译成红宝石,因为我不使用它。

编辑这没有意义......你想要 argv 还是环境?您不能通过环境传递数组,也不能通过 argv 传递命名变量。

对于 argv,不要尝试使用变量。将字符串作为参数传递给 shell 包装器。

$ sh -c $'python3 -c \'import sys; print("\\n".join(sys.argv[1:]))\' "$@"' _ 'A=1 2' B=3
A=1 2
B=3
于 2012-12-26T14:20:14.690 回答