Angenommen, ich habe ein Bash-Skript mit dem Namen geschrieben delay.sh
. Was glaubst du, macht er?#!/bin/bash
sleep 30
echo "Time's up!"
Es sieht so aus, als würde es 30 Sekunden warten und dann eine Meldung auf dem Bildschirm anzeigen. Hier gibt es keine Tricks - genau das macht er. In der Mitte befindet sich ein gefährlicher Befehl, der jedoch auskommentiert und nicht ausgeführt wird.Stellen Sie sich vor, ich führe dieses Skript erneut aus, aber jetzt möchte ich nicht 30 Sekunden warten - das ist zu lang. Ich öffne die zweite Konsole, wechsle sleep 30
zu sleep 3
und speichere die Datei. Was denkst du wird jetzt passieren?Nun, nach 30 Sekunden löscht das Skript alle meine Dateien.Dies liegt daran, dass bash den Inhalt des Skripts im Verlauf in Fragmenten liest und den Versatz in Bytes verfolgt. Wenn ich ein Zeichen aus der Zeichenfolge entferne sleep
, zeigt der Versatz für den Start des nächsten Befehls stattdessen auf r
in . Aus Sicht des Interpreters wird es in die vorherige Zeile verschoben, sodass der Befehl ab ausgeführt wird . Dies kann durch Beobachtung der Bash-Systemaufrufe unter Linux bestätigt werden. Hier ist das Problem mit Kommentaren und Abkürzungen.#rm
#
#
rm
strace bash delay.sh
openat(AT_FDCWD, "delay.sh", O_RDONLY) = 3
read(3, "#!/bin/bash\nsleep 30\n#echo \"Don'"..., 80) = 64
lseek(3, 0, SEEK_SET) = 0
dup2(3, 255) = 255
read(255, "#!/bin/bash\nsleep 30\n#echo \"Don'"..., 64) = 64
lseek(255, -43, SEEK_CUR) = 21
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 2072
read(255, "echo \"Don't execute me\"\necho \"Ti"..., 64) = 42
write(1, "Don't execute me\n", 17) = 17
write(1, "Time's up!\n", 11) = 11
read(255, "", 64) = 0
Seien Sie daher vorsichtig, wenn Sie mit der Bearbeitung des aktuell ausgeführten Bash-Skripts beginnen. Er kann den falschen Befehl ausführen oder etwas sehr Unerwartetes tun.