【发布时间】:2015-06-08 22:50:14
【问题描述】:
在 bash 中,我可以将带引号的参数传递给这样的命令:
$ printf '[%s]\n' 'hello world'
[hello world]
但如果参数来自子shell,我无法让它正常工作:
$ cat junk
'hello world'
$ printf '[%s]\n' $(cat junk)
['hello]
[world']
或者:
$ cat junk
hello world
$ printf '[%s]\n' $(cat junk)
[hello]
[world]
或者:
$ cat junk
hello\ world
$ printf '[%s]\n' $(cat junk)
[hello\]
[world]
我该如何正确地做到这一点?
编辑:解决方案也需要处理这种情况:
$ printf '[%s]\n' abc 'hello world'
[abc]
[hello world]
所以这个解决方案不起作用:
$ cat junk
abc 'hello world'
$ printf '[%s]\n' "$(cat junk)"
[abc 'hello world']
Bash quoting issue 的问题已被建议重复。但是,尚不清楚如何应用其接受的答案。以下失败:
$ cat junk
abc 'hello world'
$ FOO=($(cat junk))
$ printf '[%s]\n' "${FOO[@]}"
[abc]
['hello]
[world']
【问题讨论】:
-
“我正在尝试将命令放入变量中,但复杂的情况总是失败!” mywiki.wooledge.org/BashFAQ/050
-
如果你想要一个通用的解决方案,
printf %q就是它。也就是说:printf -v var_q %q "$var"会将"$var"的内容的eval-safe版本放入"$var_q"。 -
@rici:该解决方案在这里确实有效。请参阅上面的编辑。
-
错误。
abc 'hello world'的答案是“不要那样做”。使用 NUL 分隔的流来明确且安全地表示 shell 数组。 -
(作为另一个说明——避免 shell 局部变量的全大写变量名;这些是为系统支持的 shell 内置函数和环境变量保留的。请参阅pubs.opengroup.org/onlinepubs/009695399/basedefs/… 的 POSIX 规范,第四段,关于命名约定——记住 shell 变量和环境变量共享一个命名空间)。