zsh:命令替换和正确引用
zsh: Command substitution and proper quoting
我有一个接受文件名作为参数的脚本P
:
P file1 file2 file3 ....
我还有一个脚本G
,它生成一个(通常是短列表)文件名,每行一个文件名。在我想用 zsh 编写的主脚本中,我想使用 G
生成要由 P
处理的文件名。天真的尝试是这样的:
P $(G)
这几乎可以正常工作,只是我生活在一个恶意的人喜欢创建带有嵌入空间的文件的世界中。如果 G
会生成这样的文件列表:
one_file
a file with spaces
P
会被称为
P one_file a file with spaces
而不是
P 'one_file' 'a file with spaces'
一个明显的解决方案是将 G
和 P
粘合在一起,不是通过命令替换,而是通过某种语言的小程序(Ruby、Perl、Python, Algol68,....),它执行 P
的执行并将参数传递给从标准输入读取。
写起来很简单,甚至可以重用。但是,我想知道,zsh 及其一堆好东西是否内置了解决此问题的方法?
这可以通过以下方式实现:
P ${(f)"$(G)"}
这会将 P
称为
P 'one_file' 'a file with spaces'
如果G
的输出是
one_file
a file with spaces
解释:
$(G)
周围的双引号告诉 zsh 将 G
的输出作为一个单词(在 shell 的意义上单词单词)。
所以只要打电话
P "$(G)"
相当于
P 'one_file
a file with spaces'
这就是 参数扩展标志 f
发挥作用的地方。 ${(f)SOMEVAR}
告诉 zsh 在换行处将 $SOMEVAR
拆分为单词。除了参数(如 SOMEVAR
)之外,还可以在 ${...}
类型的参数表达式中使用命令替换(此处为 $(G)
),这会导致命令 P ${(f)"$(G)"}
.
我有一个接受文件名作为参数的脚本P
:
P file1 file2 file3 ....
我还有一个脚本G
,它生成一个(通常是短列表)文件名,每行一个文件名。在我想用 zsh 编写的主脚本中,我想使用 G
生成要由 P
处理的文件名。天真的尝试是这样的:
P $(G)
这几乎可以正常工作,只是我生活在一个恶意的人喜欢创建带有嵌入空间的文件的世界中。如果 G
会生成这样的文件列表:
one_file
a file with spaces
P
会被称为
P one_file a file with spaces
而不是
P 'one_file' 'a file with spaces'
一个明显的解决方案是将 G
和 P
粘合在一起,不是通过命令替换,而是通过某种语言的小程序(Ruby、Perl、Python, Algol68,....),它执行 P
的执行并将参数传递给从标准输入读取。
写起来很简单,甚至可以重用。但是,我想知道,zsh 及其一堆好东西是否内置了解决此问题的方法?
这可以通过以下方式实现:
P ${(f)"$(G)"}
这会将 P
称为
P 'one_file' 'a file with spaces'
如果G
的输出是
one_file
a file with spaces
解释:
$(G)
周围的双引号告诉 zsh 将 G
的输出作为一个单词(在 shell 的意义上单词单词)。
所以只要打电话
P "$(G)"
相当于
P 'one_file
a file with spaces'
这就是 参数扩展标志 f
发挥作用的地方。 ${(f)SOMEVAR}
告诉 zsh 在换行处将 $SOMEVAR
拆分为单词。除了参数(如 SOMEVAR
)之外,还可以在 ${...}
类型的参数表达式中使用命令替换(此处为 $(G)
),这会导致命令 P ${(f)"$(G)"}
.