es geht um folgendes echo-Statement:
echo "Das aktuelle Verzeichnis ist $PWD!"
Ruft man dieses Statement in einer Konsole direkt als Befehl auf, wird
-bash: !": event not found
zurückgemeldet.
Führt man dagegen dasselbe Statement über ein Bash-Shellskript
(GNU bash, version 2.05b.0(1)-release - i586-suse-linux)
aus, erfolgt die Ausgabe korrekt mit:
Das aktuelle Verzeichnis ist /tmp/test!
Warum funktioniert das echo-Statement in den Anführungszeichen nicht als
"Direkt-Aufruf" (d. h. per Konsole und nicht per Shellskript), jedoch
dagegen im Bash-Shellskript?
Wann ist es eigentlich erforderlich, den Text, den echo ausgeben soll, in
doppelte Anführungszeichen zu setzen und wann kann man sie weglassen (denn
damit funktioniert's auch beim Direkt-Aufruf)?
Wie kann man in diesem Fall - also wenn man beim Direktaufruf den
Ausgabetext in doppelte Anführungszeichen setzt - sowohl eine Variable (im
Beispielfall $PWD) auflösen und z. B. ein Ausrufezeichen korrekt mit
ausgeben?
Danke für alle guten Tips.
Thomas Wiedmann
> Hallo,
>
> es geht um folgendes echo-Statement:
> echo "Das aktuelle Verzeichnis ist $PWD!"
>
> Ruft man dieses Statement in einer Konsole direkt als Befehl auf, wird
> -bash: !": event not found
> zurückgemeldet.
>
man bash, abschnitt "History expansion"
echo "Das aktuelle Verzeichnis ist $PWD"'!'
> Führt man dagegen dasselbe Statement über ein Bash-Shellskript
> (GNU bash, version 2.05b.0(1)-release - i586-suse-linux)
> aus, erfolgt die Ausgabe korrekt mit:
> Das aktuelle Verzeichnis ist /tmp/test!
>
> Warum funktioniert das echo-Statement in den Anführungszeichen nicht als
> "Direkt-Aufruf" (d. h. per Konsole und nicht per Shellskript), jedoch
> dagegen im Bash-Shellskript?
>
> Wann ist es eigentlich erforderlich, den Text, den echo ausgeben soll, in
> doppelte Anführungszeichen zu setzen und wann kann man sie weglassen (denn
> damit funktioniert's auch beim Direkt-Aufruf)?
>
> Wie kann man in diesem Fall - also wenn man beim Direktaufruf den
> Ausgabetext in doppelte Anführungszeichen setzt - sowohl eine Variable (im
> Beispielfall $PWD) auflösen und z. B. ein Ausrufezeichen korrekt mit
> ausgeben?
>
>
> Danke für alle guten Tips.
>
> Thomas Wiedmann
--
Franz.
Logisch, weil mit einem Ausrufezeichen Bash-Events eingeleitet werden.
Was das genau ist, kannst du der Manpage entnehmen.
> Führt man dagegen dasselbe Statement über ein Bash-Shellskript
> aus, erfolgt die Ausgabe korrekt mit:
> Das aktuelle Verzeichnis ist /tmp/test!
Auch logisch, weil in Shellscripts Bash-Events nicht genutzt werden, das
! hat da also keine besondere Funktion und wird direkt ausgegeben.
> Wann ist es eigentlich erforderlich, den Text, den echo ausgeben soll,
> in doppelte Anführungszeichen zu setzen und wann kann man sie weglassen
> (denn damit funktioniert's auch beim Direkt-Aufruf)?
Bei Texten in "" führt Bash einige Ersetzungen nicht durch, unter
anderem auch nicht die für Events.
Um den Text nicht in "" einschließen zu müssen, reicht es einen \ vor
das ! zu setzen, denn damit signalisierst du Bash: "Dieses ! bitte nicht
für Events nutzen, sondern im Befehl lassen."
> Wie kann man in diesem Fall - also wenn man beim Direktaufruf den
> Ausgabetext in doppelte Anführungszeichen setzt - sowohl eine Variable
> (im Beispielfall $PWD) auflösen und z. B. ein Ausrufezeichen korrekt mit
> ausgeben?
Wenn du bash noch unmissverständlich sagen willst, welcher Teil deines
Befehles denn der Name der Variable ist, kannst du selbigen noch in {}
einschließen, dann sieht das Ganze so aus:
| echo Das aktuelle Verzeichnis ist ${PWD}\!
Lg
Michael
> Warum funktioniert das echo-Statement in den Anführungszeichen
> nicht als "Direkt-Aufruf" (d. h. per Konsole und nicht per
> Shellskript), jedoch dagegen im Bash-Shellskript?
Weil in einer interaktiven Shell standardmäßig history expansion
aktiviert ist, in einer nicht interaktiven aber nicht. Schau Dir in
beiden Fällen die Ausgabe von
echo $-
an. Mit "set +H" wirst Du die Nerverei los.
> Wann ist es eigentlich erforderlich, den Text, den echo ausgeben
> soll, in doppelte Anführungszeichen zu setzen und wann kann man sie
> weglassen (denn damit funktioniert's auch beim Direkt-Aufruf)?
Mal abgesehen von history expansion lautet die technische Version der
Antwort: Wenn Du word splitting vermeiden willst. Und das tritt auf,
wenn in der fraglichen Zeichenkette IFS-Zeichen vorkommen. Siehe:
echo -n "$IFS" | od -t x1
Standardmäßig " ", "\t" und "\n".
Der Grund für diesen merkwürdigen Effekt - expansion beim Quoting,
sonst nicht - ist die etwas skurrile Abarbeitung von quote removal
und history expansion. Da letztere direkt auf die aktuelle
Kommandozeile wirkt, sind die " hinter dem ! noch nicht entfernt.
Wenn \n direkt auf ! folgt, wird history expansion unterdrückt.
Durch das Quoting folgt aber ein anderes Zeichen auf !, nämlich ",
und dadurch wird sie aktiviert.
Also folgende Möglichkeiten:
1) history expansion komplett abschalten: set +H
2) histchars umdefinieren: siehe man bash
3) Singlequotes: echo "...$PDW"'!'
4) Backslash: echo "...$PDW"\!
Skurrilerweise geht das nicht innerhalb von "", dann bleibt der \
erhalten...
5) Space: echo "...$PDW! "
CU
Hauke
--
http://www.hauke-laging.de/ideen/
http://www.hauke-laging.de/software/
http://zeitstempel-signatur.hauke-laging.de/
Wie können 59.054.087 Leute nur so dumm sein?
> Auch logisch, weil in Shellscripts Bash-Events nicht genutzt
> werden
Nicht standardmäßig.
> Bei Texten in "" führt Bash einige Ersetzungen nicht durch, unter
> anderem auch nicht die für Events.
Dass das Unsinn ist, zeigt doch sogar das OP deutlich. Eventzugriff
bei ""-Quoting, keiner ohne Quoting.
> Um den Text nicht in "" einschließen zu müssen, reicht es einen \
> vor das ! zu setzen, denn damit signalisierst du Bash: "Dieses !
> bitte nicht für Events nutzen, sondern im Befehl lassen."
Gleich doppelt falsch. "" nimmt man nicht wegen history expansion,
und das, wofür man sie braucht, besteht weiterhin. Ein \ in ""
verhindert zwar die history expansion, bleibt aber stehen
(ungeheuerlich irgendwie - Escapewirkung ohne quote removal...).
Stimmt. Ich sollte wenn ich müde bin schlafen gehen, nicht im Usenet
posten...
>> Um den Text nicht in "" einschließen zu müssen, reicht es einen \
>> vor das ! zu setzen, denn damit signalisierst du Bash: "Dieses !
>> bitte nicht für Events nutzen, sondern im Befehl lassen."
>
> Gleich doppelt falsch. "" nimmt man nicht wegen history expansion,
> und das, wofür man sie braucht, besteht weiterhin. Ein \ in ""
> verhindert zwar die history expansion, bleibt aber stehen
> (ungeheuerlich irgendwie - Escapewirkung ohne quote removal...).
Basierte auf meinem vorherigen Missverständnis.
"" fasst mehrere Worte zu einem Argument des Befehles zusammen, was im
Falle von echo keinen Unterschied macht. Damit Bash aber das ! nicht für
Events nutzt, kann man es mit \ escapen.
Hoffentlich stimmt das jetzt. Ich geh pennen. :)
Michael
echo 'Das aktuelle Verzeichnis ist '.$pwd.'!';
> Danke für alle guten Tips.
Kein Problem :)
--
Blubb
Was sind denn Bash-Events?
Thomas Wiedmann