Ist die Verlaufserweiterung in Skripten deaktiviert?

9

Ich verstehe, dass der folgende Fehler auf !die Erweiterung des Verlaufs zurückzuführen ist:

$ echo "Hello!Tim"
bash: !Tim: event not found

Wenn ich den Befehl jedoch in ein Skript einfüge und das Skript ausführe, gibt es kein Problem:

$ cat myscript
echo "Hello!Tim"
$ bash myscript 
Hello!Tim

Warum ist das so? Erwähnt das Bash-Handbuch den Grund?

Tim
quelle
1
Gute Frage, einfach gesagt. Sehr gut gemacht!
Wildcard
Basierend auf dem, was ich hier lese : gnu.org/software/bash/manual/html_node/History-Interaction.html Ich glaube, Sie müssten einen shoptModifikator verwenden, damit es in Ihrem Skript funktioniert. Ich weiß, dass das nicht wirklich die Antwort ist, nach der Sie suchen.
Jesse_b
Was ist der Anwendungsfall? Welche Art von Skript würden Sie ausführen, um Ihren bisherigen Verlauf zu erweitern? Oder würde es frühere Befehle aus dem Skript erweitern?
Jeff Schaller
@ JeffSchaller, die Erweiterung des numerischen Verlaufs in einem Skript mit positiven Zahlen klingt nach einer wirklich schlechten Idee, aber ich könnte mir leicht Anwendungsfälle für !!oder !-2(negative / relative Verlaufszahlen) oder ähnliches vorstellen . Meistens würden sie auf andere Weise besser gelöst, aber es ist immer noch eine gute Frage, wie die Shell funktioniert (und wann Sie Ihren Ausrufen entkommen müssen / müssen!).
Wildcard

Antworten:

12

Ja, die Verlaufserweiterung ist standardmäßig nur für interaktive Shells aktiviert.

Um es für ein Shell-Skript zu aktivieren, schreiben Sie:

set -H

Um es in einer interaktiven Shell zu deaktivieren, schreiben Sie:

set +H

Verwenden Sie den folgenden Code, um festzustellen, ob die Verlaufserweiterung derzeit aktiviert ist.

case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac

Als ich anfing, eine Shell-Klasse zu unterrichten, habe ich das Handbuch ausgiebig durchgearbeitet, um herauszufinden, was eine "interaktive Shell" wirklich ist. Es ist eine Whirlpool-Frage, also lass mich dir Ärger ersparen:

Die Shell hat viele Optionen. Einige dieser Optionen werden auf unterschiedliche Weise initialisiert, wenn die Shell über ein steuerndes Terminal verfügt (oder wenn mit -ibla bla, was auch immer begonnen wird, siehe unten).

ALLE Optionen der Shell können individuell geändert werden.

Eine "interaktive Shell" ist ein trügerischer Begriff, wenn Sie versuchen, ihn genau zu definieren. Es ist wirklich nur eine Sammlung von Optionseinstellungen.

Die Frage, welche Einstellungen eine Shell interaktiv machen oder nicht, kann nicht beantwortet werden. es wird lächerlich. Es ist genau die gleiche philosophische Frage wie das Schiff des Theseus .

Wenn Sie eine interaktive Shell starten, dann aber die Verlaufserweiterung deaktivieren, das --noeditingFlag verwenden, setzen --norc, deaktivieren expand_aliasesusw. usw. In welchem ​​Sinne ist die Shell dann interaktiv? Oder wann wird es nicht mehr interaktiv? Sie können diese Fragen nicht beantworten.

Die Wahrheit ist, dass "interaktiv" nur eine praktische Bezeichnung für eine Sammlung verschiedener Shell-Optionen ist. Ebenso "nicht interaktiv". Gleiche Sache; nur eine Sammlung von Verhaltensweisen, die jeweils einzeln geändert werden können.

Fazit: Die Shell verhält sich anders, wenn sie "interaktiv" gestartet wird, als wenn sie "nicht interaktiv" gestartet wird. Der Versuch, diese Begriffe nach dem Start genau zu definieren , ist dumm. Schauen Sie sich einfach jede einzelne Option der Shell an, um ihr Verhalten zu verstehen.


Ich hatte vergessen, dass ich zusätzlich zu meiner eigenen Recherche auf dieser Seite ausführlich darüber gepostet habe.

Platzhalter
quelle
Vielen Dank. Im Handbuch finde ich nur "Diese Option ist standardmäßig für interaktive Shells aktiviert" für set -H. Es ist wahrscheinlich Ihre Schlussfolgerung, dass "die Verlaufserweiterung standardmäßig nur für interaktive Shells aktiviert ist".
Tim
@ Tim, siehe den Rest meiner Antwort. Dieser Satz des Handbuchs ist sehr rutschig und versucht, die Antwort auf "Was ist eine interaktive Shell?" Zu erhalten. Aus der Manpage heraus ist wie im Kreis zu reden. Es geht nirgendwo hin.
Wildcard
Was Sie sagen können, ist, dass das folgende Code-Snippet Ihnen immer zeigt, ob die Verlaufserweiterung in der aktuellen Shell aktiviert ist:case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
Wildcard
@ Tim, übrigens, ich habe keine Ahnung, was du meinst, dass es meine "Folgerung" ist, denn das ist die klare Bedeutung von set -H. Das ist die Histexpand-Option.
Wildcard
1
Ich habe dies an einem Skript versucht und es hat erst funktioniert, nachdem ich anhand des Skripts set -o historyüberprüft habe , set -oob es deaktiviert ist.
Daniel C. Sobral