Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable expansion is different in zsh from that in bash

Tags:

bash

shell

zsh

The following is a simple test case for what I want to illustrate.

In 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

But in 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

The last line in the zsh on above, gives me the following error

ls: invalid option -- ' '
Try `ls --help' for more information.

I think zsh is executing

ls "-a -l"

which is when I get the same error. So, how do I get bash's behavior here?

I'm not sure if I'm clear, let me know if there is something you want to know.

like image 888
sharat87 Avatar asked Jul 16 '11 04:07

sharat87


People also ask

How different is zsh from Bash?

Bash lacks syntax highlighting and auto-correction features. Zsh has syntax highlighting and auto-correction features. In bash keybinding is done using '. inputrc' and 'bind builtin'.

Is zsh and Bash same?

Key Differences Between Zsh and BashZsh is more interactive and customizable than Bash. Zsh has floating-point support that Bash does not possess. Hash data structures are supported in Zsh that are not present in Bash. The invocation features in Bash is better when comparing with Zsh.

Is zsh faster than Bash?

output and subshell The ksh and zsh seems about seven times faster than bash .

What does expansion mean in Bash?

Bash uses the value formed by expanding the rest of parameter as the new parameter ; this is then expanded and that value is used in the rest of the expansion, rather than the expansion of the original parameter . This is known as indirect expansion .


1 Answers

The difference is that (by default) zsh does not do word splitting for unquoted parameter expansions.

You can enable “normal” word splitting by setting the SH_WORD_SPLIT option or by using the = flag on an individual expansion:

ls ${=args}

or

setopt SH_WORD_SPLIT
ls $args

If your target shells support arrays (ksh, bash, zsh), then you may be better off using an array:

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

From the zsh FAQ:

  • 2.1: Differences from sh and ksh

    The classic difference is word splitting, discussed in question 3.1; this catches out very many beginning zsh users.

  • 3.1: Why does $var where var="foo bar" not do what I expect? is the FAQ that covers this question.

From the zsh Manual:

  • 14.3 Parameter Expansion

    Note in particular the fact that words of unquoted parameters are not automatically split on whitespace unless the option SH_WORD_SPLIT is set; see references to this option below for more details. This is an important difference from other shells.

  • SH_WORD_SPLIT

    Causes field splitting to be performed on unquoted parameter expansions.

like image 184
Chris Johnsen Avatar answered Oct 27 '22 19:10

Chris Johnsen