Yes-Shells bash
lesen die Datei insbesondere zeilenweise, sodass sie genauso funktioniert, wie wenn Sie sie interaktiv verwenden.
Sie werden feststellen, dass die Datei, wenn sie nicht suchbar ist (wie eine Pipe), bash
sogar jeweils ein Byte liest, um sicherzugehen, dass das \n
Zeichen nicht überschritten wird . Wenn die Datei suchbar ist, wird sie optimiert, indem ganze Blöcke gleichzeitig gelesen werden. Suchen Sie jedoch nach dem \n
.
Das heißt, Sie können Dinge tun wie:
bash << \EOF
read var
var's content
echo "$var"
EOF
Oder schreiben Sie Skripte, die sich selbst aktualisieren. Was Sie nicht könnten, wenn es Ihnen diese Garantie nicht geben würde.
Nun ist es selten, dass Sie solche Dinge tun möchten, und wie Sie herausgefunden haben, wird diese Funktion häufiger im Weg stehen, als es sinnvoll ist.
Um dies zu vermeiden, können Sie versuchen, sicherzustellen, dass Sie die Datei nicht direkt ändern (z. B. eine Kopie ändern und die Kopie an ihren Platz verschieben (wie dies zum Beispiel sed -i
oder perl -pi
einige Editoren tun)).
Oder Sie könnten Ihr Skript schreiben wie:
{
sleep 20
echo test
}; exit
(Beachten Sie, dass es wichtig ist, dass Sie exit
sich in der gleichen Zeile wie befinden }
. Sie können es jedoch auch in die geschweiften Klammern unmittelbar vor der schließenden setzen.)
oder:
main() {
sleep 20
echo test
}
main "$@"; exit
Die Shell muss das Skript erst lesen, exit
bevor sie etwas unternimmt. Dadurch wird sichergestellt, dass die Shell nicht erneut aus dem Skript liest.
Das bedeutet, dass das gesamte Skript im Speicher abgelegt wird.
Dies kann sich auch auf das Parsen des Skripts auswirken.
Zum Beispiel in bash
:
export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'
Würde das in UTF-8 codierte U + 00E9 ausgeben. Wenn Sie es jedoch ändern in:
{
export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'
}
Das \ue9
wird in dem Zeichensatz erweitert, der zu dem Zeitpunkt gültig war, als der Befehl analysiert wurde. In diesem Fall ist dies der Fall, bevor der export
Befehl ausgeführt wird.
Beachten Sie auch, dass bei Verwendung des Befehls source
aka .
bei einigen Shells die gleichen Probleme bei den Quelldateien auftreten.
Dies ist jedoch nicht der Fall, bash
wenn der source
Befehl die Datei vollständig liest, bevor er sie interpretiert. Wenn bash
Sie speziell dafür schreiben , können Sie tatsächlich davon Gebrauch machen, indem Sie am Anfang des Skripts Folgendes hinzufügen:
if [[ ! $already_sourced ]]; then
already_sourced=1
source "$0"; exit
fi
(Darauf würde ich mich jedoch nicht verlassen, da Sie sich vorstellen können, dass zukünftige Versionen von bash
dieses Verhalten ändern könnten, das derzeit als Einschränkung angesehen werden kann.) und der already_sourced
Trick ist ein bisschen spröde, da davon ausgegangen wird, dass sich die Variable nicht in der Umgebung befindet, ganz zu schweigen davon, dass er den Inhalt der Variablen BASH_SOURCE beeinflusst.)