以下是我想要说明的简单测试用例.
在bash,
# define the function f
f () { ls $args; }
# Runs the command `ls`
f
# Runs the fommand `ls -a`
args="-a"
f
# Runs the command `ls -a -l`
args="-a -l"
f
Run Code Online (Sandbox Code Playgroud)
但在zsh
# define the function f
f () { ls $args }
# Runs the command `ls`
f
# Runs the fommand `ls -a`
args="-a"
f
# I expect it to run `ls -a -l`, instead it gives me an error
args="-a -l"
f
Run Code Online (Sandbox Code Playgroud)
上面zsh中的最后一行给出了以下错误
ls: invalid option -- ' '
Try `ls --help' for more information.
Run Code Online (Sandbox Code Playgroud)
我认为zsh正在执行
ls "-a -l"
Run Code Online (Sandbox Code Playgroud)
这是我得到同样的错误.
那么,我如何在这里获得bash的行为?
我不确定我是否清楚,如果你想知道什么,请告诉我.
Chr*_*sen 30
不同之处在于(默认情况下)zsh不会对未加引号的参数扩展进行单词拆分.
您可以通过设置SH_WORD_SPLIT选项或=在单个扩展上使用标志来启用"正常"单词拆分:
ls ${=args}
Run Code Online (Sandbox Code Playgroud)
要么
setopt SH_WORD_SPLIT
ls $args
Run Code Online (Sandbox Code Playgroud)
如果您的目标shell支持数组(ksh,bash,zsh),那么最好使用数组:
args=(-a -l)
ls "${args[@]}"
Run Code Online (Sandbox Code Playgroud)
来自zsh FAQ:
经典的区别在于分词,在问题3.1中讨论过; 这引发了很多开始的zsh用户.
3.1:为什么$ var其中var ="foo bar"不符合我的预期?是涵盖此问题的常见问题解答.
从zsh手册:
特别要注意的是,除非设置了选项SH_WORD_SPLIT,否则不带引号参数的单词不会自动在空白上拆分; 有关详细信息,请参阅下面对此选项的引用.这是与其他炮弹的重要区别.
导致在不带引号的参数扩展上执行字段拆分.