Hallo, On Thu, 19 Sep 2002, Jan Trippler wrote:
On 18 Sep 2002 at 20:59, David Haller wrote: [...]
$ touch oberboerks $ foo="bla : bla fasel;: *boerks*" $ bar="`echo $foo | cut -d':' -f3`" $ echo "'$bar'" ' oberboerks'
Wirkt etwas konstruiert, der Plot ;-)
Aber natuerlich ist der konstruiert. Denn an den Fall wo ich drueber gestolpert bin erinnere ich mich leider nicht mehr.
Aber klar: Shell-Sonderzeichen hatte ich erfolgreich verdrängt, sowas muss gequoted werden.
Jep.
$ bar=`echo "$foo" | cut -d':' -f3` $ echo "'$bar'" ' *boerks*'
Merkst du was? Und ja, die bash interpretiert das `` als ein "Token", das quoten ist ueberfluessig, die Leerzeichen ueberlebens sowieso, aber andere Metazeichen nur, wenn das echo-Argument gequoted wird.
*Verwirrt den Kopf kratz* Nanu - das hatte ich doch anders in Erinnerung. Werde ich etwa senil?
jan@p4mobil:~/devel/tests> touch "x y" jan@p4mobil:~/devel/tests> a="x y" jan@p4mobil:~/devel/tests> ls `echo "$a"` ls: x: Datei oder Verzeichnis nicht gefunden ls: y: Datei oder Verzeichnis nicht gefunden jan@p4mobil:~/devel/tests> ls "`echo $a`" x y
*Verwirrt den Kopf kratz*
Ah, _sowas_ meinte ich :-) Merkwürdig - die Zuweisung an Variablen scheint nach anderen Gesetzen zu laufen. Kann es sein, dass bash-Interna da andere Wege gehen als der normalsterbliche Linux-Befehl?
Moeglich waere's. Hm. Mompl. $ cd /tmp/test/kranke_dateinamen $ for f in *; do ls -lb `echo "$f"` done [nur: no such file...] $ for f in *; do ls -lb "`echo $f`"; done Immerhin 5 von 6: Fehler beim (von mir hier jetzt mit [] umschlossenen Dateinamen(!): ["foo" and "bar"] (mit ls -b wird '\n' statt Umbruch angezeigt). Der Witz ist aber die Fehlermeldung: ls: "foo"\ and\ "bar": No such file or directory *kopfkratz und duemmlich grins* $ for f in *; do a=`echo "$f"`; ls -lb "$a"; done [alle 6 korrekt] Offenbar wird eine Variablenzuweisung anders expandiert, als wenn als Argument an ls uebergeben... Auch korrekt klappt: $ for f in *; do ls -lb "`echo \"$f\"`"; done Apropos: die Darstellung im mc verrupfts deftig in dem Ordner *eg*, und dabei hab ich ein paar fiese sogar wieder geloescht... Hm. Ich muss da mal wieder ein paar "gute" Dateinamen ergaenzen ;) Hm. Was lernen wir beide nun (und vielleicht der eine oder andere auch) daraus? Quoten bis der Arzt kommt... Wobei's ja bei Variablenzuweiseungen "weniger" braucht als als Argument fuer einen Befehl...
Das werde ich morgen mal unter Solaris testen.
Mach das ;)
Oh, IFS ist sehr praktisch und ein sehr probates Mittel. Bsp:
$ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; echo "$7"; IFS="$OIFS" /bin/bash
Hmm: grep '^dh' /etc/passwd | cut -f7 -d: oder: awk -F : ' /^dh/ { print $7 } ' /etc/passwd
sind mir persönlich lieber, aber wie gesagt: IMHO-Modus. Ich kann im ersten Moment auch nicht erkennen, welche Vorteile mir die IFS-Version bringt.
Der Vorteil stellt sich ein, wenn man mit mehreren Feldern was basteln will, da faellt dann weg x-fach ein grep | cut / awk zu verwenden, sondern man hat alle Felder direkt in _shell_-Variablen. Wenn man "nur" in awk oder perl bleibt laesst sich das natuerlich auch leicht erreichen, in perl waere das z.B.: my ($login, $x, $uid, $gid, $fullname, $home, $shell) = split(':', $_); Ok, via set hat man nicht gleich so schoene Variablennamen ;)
Auch nett:
$ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; for i; do echo "'$i'"; done"; IFS="$OIFS" ^^ typo! Ja, das '"' ist zuviel.
grep '^jan' /etc/passwd | tr ':' '\n'
Oeh, ja, nur kann man halt mit dem $i ein wenig mehr anfangen als mit der Ausgabe des tr... Siehe wie gesagt z.B. mktexupd. Das Beispiel mit der passwd ist sowieso eher weniger gut; besser (einleuchtender) ist wohl: $ OIFS="$IFS"; IFS=":"; \ for p in $PATH; do \ test -L "${p}/vim" && readlink "${p}/vim"; \ done; \ IFS="$OIFS" (wobei der Schleifenkoerper wieder nur ein eher "dummes" Beispiel ist). Variablen mit ':' als Pfadtrenner gibt's ja noch mehr, z.B. LD_LIBRARY_PATH, MANPATH, INFO{PATH,DIR}...
Ich habe das Umbauen von IFS auch schon verwendet, konnte mich aber nie so richtig damit anfreunden und nehme wenn möglich was anderes.
In Scripts sehe ich den Einsatz von set -- eh kritisch, weil ich mir damit u. U. die Original- Parameter überschreibe.
Wo ist das Problem? ARGV="$@"; OIFS="$IFS"; IFS=":" set -- `grep '^name' /etc/pwasswd` IFS="$OIFS" # mach was mit $@ set -- $ARGV
BTW: Geht denn das, Positionsparameter $10 usw.?
Na klar geht das, man muss aber ${nn} verwenden, da die bash sonst aus $13 ein ${1}3 macht.
Gucke da, ich habe bisher (hatte ich mal so gelernt) immer brav shift gemacht. Noch ein Fall für meinen Solaris-Test ;-)
*bg* -dnh -- A common mistake that people make, when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. -- Douglas Adams - Mostly Harmless