Roy Marples wrote:

> On Thu, 2007-10-04 at 05:03 +0100, Steve Long wrote:
>> Donnie Berkholz wrote:
>> 
>> > spec=$(echo ${CHOST} | cut -d- -f3)
>> > 
>> You can do this without resort to an external process:
>> IFS=-
>> read _ _ spec _ <<< "$CHOST"
>> unset IFS
>> - or you can do:
>> IFS=-
>> arr=($CHOST)
>> unset IFS
>> spec=${arr[2]}
> 
> See, another use of bash arrays just because you can?
No, because it's expressive and it works cleanly. If it's an important array
I can refer to it throughout a script without having to reallocate storage
or forcing the shell to expand it for a function call. More a case of: hey,
you know you can do this with arrays and IFS? Ain't it neat? :D

> IFS=-
> set -- ${CHOST}
> spec=$2
> 
> Works fine in bash - and other shells.
>
Yeah fine, there are kludgy workarounds; so what? Doesn't mean I want to use
them. ;)
In actual fact, I'd be more likely to use parameter expansion than set, eg:
spec=${CHOST#*-*-} # chop first two fields off so spec is fields 3 on
spec=${spec%%-*} # chop all but first off so left with just field 3
..which I believe works in sh[1] as well. The point for me, however, is not
whether sh can be kludged to do something, it's what the most efficient
ways to do something in scripts are. Whether you use pe, read or an array,
avoiding externals leads to quicker scripts.[2]

The exceptions are where the external provides functionality you can't
easily reproduce in bash (like ed or find) or where it can perform the job
more efficiently (like awk on large files.) It really depends on the task,
but learning to do break the problem down for builtins a) is fun ;P and b)
teaches generic programming, transferable to other languages.

> You need to preserve IFS when changing it, however. Unless of course,
> you're doing this in a function so you can just local IFS=-
>
Perhaps, although at the level of an ebuild or a script I am writing, the
default IFS is what I start with. If it were a function for a sourced
library, then yeah there's a valid argument for preserving the caller's
IFS. (I prefer to work with an assumption of default, ie spaces tabs and
newlines.)

> Here's a snippet from b2's localmount init script.
(I'm guessing the first line lost it's first character?) 
> IFS=${IFS} SIFS=${IFS-y}
> FS=$IFS:
> for x in ${NO_UMOUNTS} ${RC_NO_UMOUNTS} ; do
>    no_umounts="${no_umounts}|${x}"
> one
> if [ "${SIFS}" = "y" ] ; then
>    IFS=$OIFS
> else
>    unset IFS
> fi
> 
I wouldn't bother with the SIFS stuff, I'd just do:
OIFS=$IFS
..blah blah..
IFS=$OIFS

FS=$IFS: looks dangerous as well; how can you know what IFS contains (this
seems to hope it's whitespace) on function entry? (Which is the whole point
of saving it.) IFS=$' \t\n:' or summat would be better.

[1] http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
[2] http://forum.bash-hackers.org/index.php?topic=51.0 -- teh power of
extglob ;P


-- 
[EMAIL PROTECTED] mailing list

Reply via email to