Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Expansion order



On Tue, Jan 25, 2005 at 03:41:50PM +0100, Mads Martin Joergensen wrote:
> Hey together,
> 
> $ export LS_OPTIONS="-N --color=tty -T 0"
> $ alias ls='ls $LS_OPTIONS'
> $ ls
> /bin/ls: invalid option --
> Try `/bin/ls --help' for more information.
> 
> How come the zsh is doing the expansion in this case differently from
> csh, tcsh, bash and sh?
> 
> If it's a configuration option or such, I would be grateful to know. I
> looked through the expansion man-pages, but I might have missed it.
[...]

See question 3.1 in the FAQ
http://zsh.sunsite.dk/FAQ/zshfaq03.html#l17

Even with other Bourne like shells, it's not a good idea to
write it this way as it relies on the current value of IFS.
(if you change IFS, your ls will stop working).

Here, you want LS_OPTIONS to be an array, not a string.

LS_OPTIONS=(-N --color=tty -T 0)
alias ls='ls "${LS_OPTIONS[@]"'

Or if LS_OPTIONS has to be an environment variable, then you'd
better ensure the the right value of IFS is used:

export LS_OPTIONS='-N,--color=tty,-T,0'
ls() {
  (
    IFS=,
    set -f
    exec command ls $LS_OPTIONS "$@"
  )
}

or for zsh, where word splitting and filename generation are
thanksfully not implicit:

export LS_OPTIONS='-N,--color=tty,-T,0'
ls() {
  local IFS=,
  command ls $=LS_OPTIONS "$@"
}

" " (space) is not a good choice of <character> for a
<character> separated list, as it doesn't allows empty elements,
that's why I used "," instead above.

Alternatively, you may consider "LS_OPTIONS" as a part of a
shell command line, so that can have:

LS_OPTIONS='-foo "arg with spaces" -empty ""'
or
LS_OPTIONS='--color="$([ -t 1 ] && echo yes || echo no)"'

Then, you can use it as:

ls() {
  eval "command ls $LS_OPTIONS \"\$@\""
}

Which should work in zsh as well as in POSIX shells.

-- 
Stéphane



Messages sorted by: Reverse Date, Date, Thread, Author