Yes-Shells bashlesen 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), bashsogar jeweils ein Byte liest, um sicherzugehen, dass das \nZeichen 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 -ioder perl -pieinige Editoren tun)).
Oder Sie könnten Ihr Skript schreiben wie:
{
sleep 20
echo test
}; exit
(Beachten Sie, dass es wichtig ist, dass Sie exitsich 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, exitbevor 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 \ue9wird 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 exportBefehl ausgeführt wird.
Beachten Sie auch, dass bei Verwendung des Befehls sourceaka .bei einigen Shells die gleichen Probleme bei den Quelldateien auftreten.
Dies ist jedoch nicht der Fall, bashwenn der sourceBefehl die Datei vollständig liest, bevor er sie interpretiert. Wenn bashSie 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 bashdieses Verhalten ändern könnten, das derzeit als Einschränkung angesehen werden kann.) und der already_sourcedTrick 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.)