bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Short list of issues with various expansions and IFS


From: Chet Ramey
Subject: Re: Short list of issues with various expansions and IFS
Date: Sun, 13 Jan 2013 19:55:36 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/17.0 Thunderbird/17.0

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 1/9/13 2:46 PM, Dan Douglas wrote:
> I'll lump a few issues together here...
> 
>  1. Backslash escape adjacent to "$@" expansion separates words.

Yes, this is a bug.  I will fix it for the next version.

>     $ set -- abc def ghi; printf '<%s> ' "123 $@ 456"; echo
>     <123 abc> <def> <ghi 456>
>     $ set -- abc def ghi; printf '<%s> ' "123 $@\ 456"; echo
>     <123 abc> <def> <ghi\> <456>
>  
> Other shells don't do this (though it might even be useful if the backslash 
> were removed from the result). Depends on the previous fix for
> 4.2-p36

You can't remove the backslash; space is not one of the characters "for
which backslash retains its special meaning" in double quotes.

>  2. IFS side-effects don't take effect during expansion.

Yeah, this is a tough one.  If you want side effects of assignments to IFS
to affect subsequent expansions, you have to have a way to ensure that the
previous expansions of $* are split correctly.  I might end up having to
introduce new state flags to handle this, but I have to think about it some
more.

(BTW, zsh's results look like they're the most correct, if you expect the
early IFS assignments to affect later expansions.  See below.)

> It isn't clear to me which of these are correct. Bash's interpretation is 
> unique.
> 
>       for sh in bb {{d,b}a,po,{m,}k,z}sh; do
>               printf '%-5s ' "${sh}:"
>               "$sh" /dev/fd/0
>       done <<\EOF
>       ${ZSH_VERSION+:} false && emulate sh
>       set -f -- a b c
>       unset -v IFS
>       printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}"
>       echo
>       EOF
> 
> bb  : <a b cabc> <a-b-c>
> dash: <a b cabc> <a-b-c>

The ash derivatives are clearly wrong; you only concatenate the positional
parameters if the expansion happens in a double-quoted string.

> bash: <a> <b> <ca> <b> <c-a b c>

Probably wrong; changes to IFS don't affect the expansions of ${*}
(and what's worse, the new value of IFS doesn't affect later expansions
of $*).

> posh: <a> <b> <ca b c> <a-b-c>
> mksh: <a> <b> <ca b c> <a-b-c>

pd-ksh derivatives are wrong; the second expansion of ${*} needs to be
split.

> ksh : <a> <b> <ca> <b> <c> <a b c>

Wrong: the last expansion of "${*}" needs to use the first character of
$IFS if you expect assignments to affect later expansions.

> zsh : <a> <b> <ca> <b> <c> <a-b-c>

This looks right.

>  3. Another IFS oddity via "command"
> 
> IFS can be given "two values at once" through the environment of a 
> redirection.

I have to look at this one.  It's clear that the temporary environment
given to `command' is like the temp environment supplied to `eval', and
needs to persist through all of the commands executed by `command'.  I
have to figure out whether that temporary environment counts as the temp
environment to `cat' (I don't think so) and how to reconcile the variable
lookups during redirection expansion.

>  4. Command substitution in redirection evaluated twice on error.

Yes, it should not be evaluated twice.  I'm going to fix it by disabling
command substitution when expanding the filename for the error message,
rather than disabling the expansion altogether.

Chet

- -- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    chet@case.edu    http://cnswww.cns.cwru.edu/~chet/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with undefined - http://www.enigmail.net/

iEYEARECAAYFAlDzV4IACgkQu1hp8GTqdKvPVgCghnGf5hyAGDJ3rWMNeX+8y3yh
5B0AniKzE+tDQLsNlqB4oEIXsqDBp8YH
=yMOs
-----END PGP SIGNATURE-----



reply via email to

[Prev in Thread] Current Thread [Next in Thread]