Platzierung von Bash-Skriptvariablen

8

Ich habe angefangen, Bash-Scripting zu lernen und verwende das Bash-Scripting-Tutorial

Dort steht es

Bevor Bash jede Zeile unseres Skripts interpretiert (oder ausführt), prüft es zunächst, ob Variablennamen vorhanden sind . Für jede identifizierte Variable wird der Variablenname durch seinen Wert ersetzt. Dann wird diese Codezeile ausgeführt und der Vorgang in der nächsten Zeile erneut gestartet.

Läuft Bash also zuerst das gesamte Skript durch, um Variablen zu finden? Ich bin mir nicht sicher, ob der Autor dies versucht hat, aber wenn ja, denke ich, ist es nicht korrekt?

wenn ich ausführe:

#!/bin/bash


echo "hello $USERR"



USERR=John

Ich bekomme helloals Ergebnis.

Wenn ich renne:

#!/bin/bash


USERR=John

echo "hello $USERR"

dann bekomme ich hello Johnals Ergebnis.

blabla_trace
quelle
6
Ich würde ein Tutorial ignorieren, dessen erstes Codebeispiel den elementarsten Fehler macht, Parametererweiterungen nicht zu zitieren (und das zu vergessen --und nicht auf Fehler von Befehlen zu prüfen ...). Sicherheitsimplikationen des Vergessens, eine Variable in Bash / POSIX-Shells zu zitieren
Stéphane Chazelas

Antworten:

11

Läuft Bash also zuerst das gesamte Skript durch, um Variablen zu finden?

Nee. Wie Sie selbst in Ihrem Beispiel festgestellt haben, werden Bash-Skripte von oben nach unten ausgeführt.

Es empfiehlt sich, alle Variablen, die Sie benötigen, oben in Ihrem Skript zu definieren.

maulinglawns
quelle
Bash durchläuft jedoch zuerst Zeilen , um Variablen zu finden. x=1; x=2 echo "$x"druckt, 1weil $xes ersetzt wird, bevor x=2 echo "$x"es ausgeführt wird.
BallpointBen
9

Das ist eine sehr schlampige Art zu sagen, dass die Shell jeden Befehl nach Erweiterungen durchsucht, wie zum Beispiel Variablen (aber auch Befehlsersetzungen usw.).

Der Text könnte so interpretiert werden, dass die Shell das gesamte Skript liest und vor der Ausführung in jeder Zeile nach Variablen sucht. Das ist nicht so. Es verarbeitet das Skript Befehl für Befehl, nicht Zeile für Zeile. Ein Befehl kann mehrere Zeilen umfassen. Ein Befehl wird erst verarbeitet, wenn der Shell-Interpreter ihn bei der Ausführung des Skripts erreicht.

Die bashShell führt mit jedem Befehl Folgendes aus, bevor er ausgeführt wird:

  1. Klammererweiterung
  2. Tilde-Erweiterung
  3. Parameter- und Variablenerweiterung
  4. arithmetische Erweiterung
  5. Befehlsersetzung (von links nach rechts)
  6. Wortteilung
  7. Pfadnamenerweiterung
  8. Entfernung von Zitaten
Kusalananda
quelle
Ja, so habe ich die Zeile interpretiert. Ich werde das Material trotzdem durchgehen, aber gibt es Bücher, Websites, die einen Blick wert sind? Vielen Dank im Voraus!
blabla_trace
3
@blablatrace Ich würde unix.stackexchange.com als gute Ressource zum Erlernen der Verwendung und Programmierung in der Shell empfehlen , obwohl die Qualität manchmal etwas unterschiedlich ist. Die Community ist im Allgemeinen auch freundlich. Schauen Sie sich auch den Chat an (manchmal etwas leer).
Kusalananda
Vielleicht sollten Sie klarer sein, was Sie unter "Prozessumleitungen" verstehen - ich verstehe, worum es geht (z. B. "a ="> "; Echo yes $ a foo" schreibt nicht "yes" in "foo"). ;; Umleitungen werden jedoch sicherlich NACH Erweiterungen verarbeitet, z. 'a = "ab c"; echo> $ a 'ist ein Fehler, der zeigt, dass die Shell versucht, die Umleitung zu verstehen, nachdem sie eine variable Erweiterung durchgeführt hat. Und Variablenzuweisungen sind ebenso speziell wie Umleitungen - 'q = a; $ q = 12 cmd 'versucht, einen Befehl mit dem Namen' a = 12 'auszuführen, nicht' cmd 'mit einer var a = 12 in seiner Umgebung.
Mosvy
Wenn es auch, mehrere einfache Befehle auf der gleichen Linie sind (getrennt durch sind ;, ||oder &&), sind sie erweitert und einer nach dem anderen ausgeführt. Wird daher foo="some value"; echo "$foo"gedruckt, some valueda der Verweis auf $fooerst erweitert wird, nachdem der Zuweisungsbefehl ausgeführt wurde. Übrigens können Befehle auch durch getrennt werden &, aber das ist ein Sonderfall. Damit wird der erste Befehl im Hintergrund ausgeführt, sodass der zweite Befehl nicht darauf wartet, dass er beendet wird.
Gordon Davisson
2
Andere gute Bash-Scripting-Ressourcen: Gregs Wiki und BashFAQ , das Bash Hacker's Wiki und shellcheck.net , um Ihre Skripte auf häufige Probleme zu überprüfen.
Gordon Davisson