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

Re: Bug#95430 acknowledged by developer (Re: Bug#95430: ash: word-splitting changes break shell scripts)

Zack Weinberg <zackw@stanford.edu> wrote:
>> On Fri, Apr 27, 2001 at 12:22:18AM -0700, Zack Weinberg wrote:
>> > 
>> > ash 0.3.8-1 incorporates changes in word splitting which break common
>> > shell scripts, such as /usr/bin/mktexpk and the 'mklibgcc' script used
>> > when compiling GCC.
>> > 
>> > #! /bin/ash
>> > OIFS=$IFS
>> > IFS=,
>> > set `echo fnord,a,b,c`
>> > IFS=$OIFS
>> > CMD="echo $@"
>> > $CMD
>> Sorry, but this is broken.  This assumes that IFS is set to begin with
>> which may not be the case.

> I have consulted the Single Unix Standard and can find only dubious
> justification for this assertion.  It never flat out says whether IFS
> is to be set on entry to the shell or not.  However, I note this
> paragraph:

It's wrong regardless of whether the shell sets it.  The whole point of
saving IFS is so that you can restore it to its original value, which can
be whatever the previous user has set it to, including the case of it not
being set at all.  If your code can't handle that, then please don't save
the value at all.

BTW, there is a shorter way of saving it:

> # IFS
> #    Input field separators: a string treated as a list of characters
> #    that is used for field splitting and to split lines into fields
> #    with the read command. If IFS is not set, the shell will behave
> #    as if the value of IFS were the space, tab and newline
> #    characters. (See Field Splitting .)

> I could read that as requiring that if IFS is unset, then you get
> "<space><tab><newline>" if you inspect its value, NOT the null string.

I think this is stretching it a bit.  Please try this in any shell:

unset IFS
echo ${IFS+yes}

If you get yes from any shell, then you might have a point.  I've certainly
never seen one that hehaved like that.

> In any case, your change is a gratuitous divergence from the upstream
> code and a deliberate breakage of consensus shell behavior.  My script
> functions correctly with every Bourne-descended shell I have access to
> except ash 0.3.8-1.  (In addition to bash, pdksh, and previous
> versions of ash, I tried the /bin/sh provided by Solaris, HP-UX, IRIX,
> and Digital Unix, and the /bin/ksh and /usr/xpg4/bin/sh provided by
> Solaris.)  Irrespective of what the standard says, you cannot
> introduce changes into /bin/sh which make it behave differently from
> every other shell out there.  Especially if they have the potential to
> break every shell script which uses some feature.

I can understand how frustrating it is to have your scripts broken by
this.  But the fact remains that it's the scripts that are broken, not the

Are your functions supposed to be called by other scripts in general? If
so, then it's particularly important to handle the case of an unset IFS.
Debian GNU/Linux 2.2 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

Reply to: