在bash中,我可以将引用的参数传递给这样的命令:
$ printf '[%s]\n' 'hello world'
[hello world]
但如果争论来自子壳,我无法正常工作:
$ 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']
答案 0 :(得分:0)
这里没有一个好的解决方案,但你可以选择不好的解决方案。
使用NUL分隔的文件流是最安全的方法;从字面上看,任何C字符串(因此,任何字符串bash都可以存储为数组元素)都可以这种方式编写和读取。
grunt.config('directory')
如果有效参数不能包含换行符,您可能希望在阅读方面忽略mkdir: {
all: {
options: {
mode: 0777,
create: ['<%= directory %>']
}
}
}
并将写作方# write file as a NUL-delimited stream
printf '%s\0' abc 'hello world' >junk
# read file as an array
foo=( )
while IFS= read -r -d '' entry; do
foo+=( "$entry" )
done <junk
更改为-d ''
以使用换行而不是NUL。请注意,UNIX文件名可以包含换行符,因此如果您的可能参数包含文件名,则此方法是不明智的。
\0
\n
有一些围绕多行字符串的极端情况,其解析不像完全与shell的行为完全相同。然而,这是一个99%的解决方案。
Python标准库foo=( )
while IFS= read -r -d '' entry; do
foo+=( "$entry" )
done < <(xargs printf '%s\0' <junk)
模块支持符合POSIX标准的字符串标记,这比标准xargs
实现的标准更为真实。请注意,shlex
等bash / ksh扩展名不受尊重。
xargs
...具体来说,如果可以编写$'foo'
的内容以包含对shell敏感的代码(例如shlex_split() {
python -c '
import shlex, sys
for item in shlex.split(sys.stdin.read()):
sys.stdout.write(item + "\0")
'
}
while IFS= read -r -d '' entry; do
foo+=( "$entry" )
done < <(shlex_split <junk)
),那么您不想使用其中任何一个:
junk
如果您想确保$(rm -rf /)
以这种方式安全阅读,并且您控制写入它的代码,请考虑:
# use declare
declare "foo=($(cat junk))"
# ...or use eval directly
eval "foo=( $(cat junk) )"
或者,您可以使用:
foo
和
# write foo array to junk in an eval-safe way, if it contains at least one element
{ printf '%q ' "${foo[@]}" && printf '\n'; } >junk;