zsh: 命令替换和正确引用

5

我有一个脚本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'

一个显然的解决方案是将 GP 粘合在一起,而不是通过命令替换,而是使用某种语言(如Ruby、Perl、Python、Algol68等)编写一个小程序,该程序执行 P 并将参数传递给从标准输入读取的操作。
这很容易编写,甚至可以被重复使用。但是,我想知道,是否带有各种好处的 zsh 没有内置解决此问题的方法?
1个回答

5
这可以通过以下方式实现:
P ${(f)"$(G)"}

这将调用P

P 'one_file' 'a file with spaces'

如果 G 的输出是

one_file
a file with spaces

解释:

$(G) 周围的双引号告诉 zshG 的输出作为一个单词(在 shell 中的意思是单个单词)。

因此,只需调用

P "$(G)"

将其翻译为中文是“等同于”。
P 'one_file
a file with spaces'

这就是 参数展开标志 f 起作用的地方。 ${(f)SOMEVAR} 告诉 zsh 在换行处将 $SOMEVAR 分割成单词。在 ${...} 类型的参数表达式中,除了可以使用参数(如 SOMEVAR)外,还可以使用命令替换(这里是 $(G)),从而导致执行命令 P ${(f)"$(G)"}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接