[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gnulib-tool nits
From: |
Bruno Haible |
Subject: |
Re: gnulib-tool nits |
Date: |
Sat, 23 Jun 2007 21:09:42 +0200 |
User-agent: |
KMail/1.5.4 |
Hi Ralf.
> This isn't reliable either: bash 3.1.17 and ksh do this:
> $ ( d=:a:b:; IFS=:; for i in $d ; do echo .$i. ; done )
> ..
> .a.
> .b.
>
> but pdksh does this:
> $ ( d=:a:b:; IFS=:; for i in $d ; do echo .$i. ; done )
> ..
> .a.
> .b.
> ..
This is only the tip of the iceberg. I tested also the behaviour of empty
fields in the middle (e.g. PATH=/usr/local/bin::/usr/bin:/usr/bin).
The test is this:
/bin/sh -c 'd=:a:b::c:; IFS=:; for i in $d ; do echo .$i. ; done'
I got four different results:
Result A:
.a.
.b.
.c.
Result B:
.a.
.b.
..
.c.
Result C:
..
.a.
.b.
..
.c.
Result D:
..
.a.
.b.
..
.c.
..
And here's the matrix:
/bin/sh /bin/ksh
/usr/xpg4/bin/sh
AIX 5.1 C C
HP-UX 11 C C
IRIX 6.5 B B
OSF/1 4.0, 5.1 A B
Solaris 7, 10 A C
FreeBSD 6 D
MacOS X 10.3 (bash) C
bash 1.14.7 C
bash 2.02.1-2.05 C
bash 3.0-3.2 C
zsh 4.1.1 D
> I think SUSv3 wording is saying that pdksh is right and bash is wrong. :-/
I cannot find any specification of it at all in POSIX: The relevant text at
http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_05
says (for the case IFS=:):
"the shell shall scan ... for field splitting and multiple fields can result.
The shell shall treat each character of the IFS as a delimiter and use the
delimiters to split ... into fields.
Each occurrence in the input of ':' ... shall delimit a field ..."
It is not clear whether empty fields can occur at all, and under which
conditions they appear at the front or at the end of the result.
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_161
is silent about it.
So, it seems, in order to get portable behaviour, you need to avoid empty
fields:
pathx=`echo ":$PATH:" | sed -e 's/:::*/:.:/g'`
But then use IFS (so that PATH elements containing spaces are handled
correctly), ignoring empty fields from the cases C and D. In summary,
something like this:
pathx=`echo ":$PATH:" | sed -e 's/:::*/:.:/g' -e 's/^://' -e 's/:\$//'`
save_IFS=$IFS
IFS=:
for d in $pathx; do
IFS=$save_IFS
...
done
IFS=$save_IFS
Bruno
Re: gnulib-tool nits, Paul Eggert, 2007/06/26