Variable expansion is different in zsh from that in bash
Asked Answered
Z

1

32

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.

Zavras answered 16/7, 2011 at 4:43 Comment(3)
This doesn't answer your question, but I'd consider this better: f () { ls "$@"; }; f -a -lTubb
@glenn, Yes, definitely is. As I said, this is just an illustration of a bigger problem I have, where I have to use the args variable.Zavras
@ShrikantSharat If you're writing scripts for bash and zsh (and ksh), don't do this with the args variable. Use an array instead.Acierate
B
61

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:

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.

Breathing answered 16/7, 2011 at 5:1 Comment(3)
Yes, that's just what I wanted. I didn't know what to google or where to look for, could you point to some documentation that explains this? Thanks for the answer.Zavras
All my versions of bash (3.2.48, and 4.2.10) reject ${=…}. I am pretty sure is it specific to zsh. If you are targeting bash and zsh, then you might try an array (in my updated answer).Breathing
right, it doesn't work. am checking for zsh and using the SH_WORD_SPLIT option in a sub-shell. I wish I could use arrays, but I have to use a variable :)Zavras

© 2022 - 2024 — McMap. All rights reserved.