zsh: Command substitution and proper quoting

我怕爱的太早我们不能终老 提交于 2019-12-12 16:05:44

问题


I have a script P which accepts file names as parameters:

P file1 file2 file3 ....

I also have a script G which generates a (typically short list) of file names, one file name per line. In a master script which I would like to write in zsh, I want to use G to generate the file names to be processed by P. The naive attempt goes like this:

P $(G)

This works nearly well, only that I'm living in a world where malicious people enjoy creating files with embedded spaces. If G would generate the list of files like this:

one_file 
a file with spaces

P would be called as

P one_file a file with spaces

instead of

P 'one_file' 'a file with spaces'

One obvious solution would be to glue G and P together not by command substitution, but by a small program in some language (Ruby, Perl, Python, Algol68,....), which does an exec of P and passes the parameters to a read from stdin.

This would be trivial to write and could even be made reusable. However, I wonder, whether zsh with its grabbag of goodies would not have a solution for this problem builtin?


回答1:


This can be achieved with:

P ${(f)"$(G)"}

which will call P as

P 'one_file' 'a file with spaces'

if the output of G is

one_file
a file with spaces

Explanation:

The double quotes around $(G) tell zsh to take the output of G as one word (in the shell sense of the word word).

So just calling

P "$(G)"

would be equivaent of

P 'one_file
a file with spaces'

This is where the Parameter Expansion Flag f comes into play. ${(f)SOMEVAR} tells zsh to split $SOMEVAR into words at newlines. Instead of a parameter (like SOMEVAR) one can also use a command substitution (here $(G)) inside ${...} type parmeter expressions, which leads to the the command P ${(f)"$(G)"}.



来源:https://stackoverflow.com/questions/29028828/zsh-command-substitution-and-proper-quoting

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!