以下是我想要说明的简单测试用例。
在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
但是在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
上面zsh中的最后一行,给出了以下错误
ls: invalid option -- ' '
Try `ls --help' for more information.
我认为zsh正在执行
ls "-a -l"
这是我得到同样的错误。
那么,我如何在这里获得bash的行为?
我不确定我是否清楚,请告诉我你是否想知道。
答案 0 :(得分:27)
不同之处在于(默认情况下) zsh 不会对未加引号的参数扩展进行分词。
您可以通过设置SH_WORD_SPLIT选项或在单个扩展上使用=
标志来启用“正常”字词拆分:
ls ${=args}
或
setopt SH_WORD_SPLIT
ls $args
如果您的目标shell支持数组( ksh , bash , zsh ),那么您最好使用数组:
args=(-a -l)
ls "${args[@]}"
来自zsh FAQ:
2.1: Differences from sh and ksh
经典差异是单词分裂,在问题3.1中讨论过;这引发了很多开始使用zsh的用户。
3.1: Why does $var where var="foo bar" not do what I expect?是解决此问题的常见问题解答。
来自zsh Manual:
特别注意,除非设置了选项SH_WORD_SPLIT,否则不加引号参数的单词不会自动在空白上拆分;有关详细信息,请参阅下面对此选项的引用。这是与其他炮弹的重要区别。
导致在不带引号的参数扩展上执行字段拆分。