2011-07-16 68 views
9

以下是我想说明的一个简单测试用例。变量扩展在zsh中与bash中的变量不同

在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的行为呢?

我不确定我是否清楚,请告诉我是否有您想要知道的事情。

+2

这不回答你的问题,但我认为这是更好的:'F(){LS “$ @”; }; f -a -l' –

+0

@glenn,是的,绝对是。正如我所说的,这只是一个更大的问题的例子,我必须使用args变量。 –

+1

@ShrikantSharat如果您正在为bash和zsh(和ksh)编写脚本,请不要使用'args'变量来执行此操作。改用数组。 – Gilles

回答

21

区别在于(默认情况下)zsh不针对未加引号的参数展开进行分词。

您可以通过设置SH_WORD_SPLIT选项或使用=标志上的单个扩张使“正常”的分词:

ls ${=args} 

setopt SH_WORD_SPLIT 
ls $args 

如果你的目标炮弹支持阵列( ksh,bash,zsh),那么你最好使用数组:

args=(-a -l) 
ls "${args[@]}" 

zsh FAQ

zsh Manual

  • 14.3 Parameter Expansion

    请特别注意的事实是没有引用的参数的话,不会自动上的空白,除非选项SH_WORD_SPLIT设置分割;有关更多详细信息,请参阅下面对此选项的引用这是与其他shell的重要区别。

  • SH_WORD_SPLIT

    成因场分裂要在不带引号的参数扩展进行。

+0

是的,那正是我想要的。我不知道该在哪里寻找或寻找什么,你能指出一些解释这个的文档吗?感谢你的回答。 –

+0

另外,是否与bash兼容的'$ {= args}'用法?我的测试证实它是... –

+3

* bash *(3.2.48和4.2.10)的所有版本都拒绝'$ {= ...}'。我很确定它是特定于* zsh *。如果你的目标是* bash *和* zsh *,那么你可以尝试一个数组(在我更新的答案中)。 –