1 |
Roy Marples wrote: |
2 |
|
3 |
> On Thu, 2007-10-04 at 05:03 +0100, Steve Long wrote: |
4 |
>> Donnie Berkholz wrote: |
5 |
>> |
6 |
>> > spec=$(echo ${CHOST} | cut -d- -f3) |
7 |
>> > |
8 |
>> You can do this without resort to an external process: |
9 |
>> IFS=- |
10 |
>> read _ _ spec _ <<< "$CHOST" |
11 |
>> unset IFS |
12 |
>> - or you can do: |
13 |
>> IFS=- |
14 |
>> arr=($CHOST) |
15 |
>> unset IFS |
16 |
>> spec=${arr[2]} |
17 |
> |
18 |
> See, another use of bash arrays just because you can? |
19 |
No, because it's expressive and it works cleanly. If it's an important array |
20 |
I can refer to it throughout a script without having to reallocate storage |
21 |
or forcing the shell to expand it for a function call. More a case of: hey, |
22 |
you know you can do this with arrays and IFS? Ain't it neat? :D |
23 |
|
24 |
> IFS=- |
25 |
> set -- ${CHOST} |
26 |
> spec=$2 |
27 |
> |
28 |
> Works fine in bash - and other shells. |
29 |
> |
30 |
Yeah fine, there are kludgy workarounds; so what? Doesn't mean I want to use |
31 |
them. ;) |
32 |
In actual fact, I'd be more likely to use parameter expansion than set, eg: |
33 |
spec=${CHOST#*-*-} # chop first two fields off so spec is fields 3 on |
34 |
spec=${spec%%-*} # chop all but first off so left with just field 3 |
35 |
..which I believe works in sh[1] as well. The point for me, however, is not |
36 |
whether sh can be kludged to do something, it's what the most efficient |
37 |
ways to do something in scripts are. Whether you use pe, read or an array, |
38 |
avoiding externals leads to quicker scripts.[2] |
39 |
|
40 |
The exceptions are where the external provides functionality you can't |
41 |
easily reproduce in bash (like ed or find) or where it can perform the job |
42 |
more efficiently (like awk on large files.) It really depends on the task, |
43 |
but learning to do break the problem down for builtins a) is fun ;P and b) |
44 |
teaches generic programming, transferable to other languages. |
45 |
|
46 |
> You need to preserve IFS when changing it, however. Unless of course, |
47 |
> you're doing this in a function so you can just local IFS=- |
48 |
> |
49 |
Perhaps, although at the level of an ebuild or a script I am writing, the |
50 |
default IFS is what I start with. If it were a function for a sourced |
51 |
library, then yeah there's a valid argument for preserving the caller's |
52 |
IFS. (I prefer to work with an assumption of default, ie spaces tabs and |
53 |
newlines.) |
54 |
|
55 |
> Here's a snippet from b2's localmount init script. |
56 |
(I'm guessing the first line lost it's first character?) |
57 |
> IFS=${IFS} SIFS=${IFS-y} |
58 |
> FS=$IFS: |
59 |
> for x in ${NO_UMOUNTS} ${RC_NO_UMOUNTS} ; do |
60 |
> no_umounts="${no_umounts}|${x}" |
61 |
> one |
62 |
> if [ "${SIFS}" = "y" ] ; then |
63 |
> IFS=$OIFS |
64 |
> else |
65 |
> unset IFS |
66 |
> fi |
67 |
> |
68 |
I wouldn't bother with the SIFS stuff, I'd just do: |
69 |
OIFS=$IFS |
70 |
..blah blah.. |
71 |
IFS=$OIFS |
72 |
|
73 |
FS=$IFS: looks dangerous as well; how can you know what IFS contains (this |
74 |
seems to hope it's whitespace) on function entry? (Which is the whole point |
75 |
of saving it.) IFS=$' \t\n:' or summat would be better. |
76 |
|
77 |
[1] http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html |
78 |
[2] http://forum.bash-hackers.org/index.php?topic=51.0 -- teh power of |
79 |
extglob ;P |
80 |
|
81 |
|
82 |
-- |
83 |
gentoo-dev@g.o mailing list |