Ein ähnliches Skript ohne sudo, aber ähnliche Ergebnisse:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
Mit bashdem Rest des Skripts geht als Eingabe sed, mit dashihm, der Schale interpretiert.
Laufen straceauf diesen: dashLiest einen Block des Skripts (hier acht KB, mehr als genug, um das gesamte Skript zu speichern) und erzeugt dann sed:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 8192) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
Dies bedeutet, dass sich das Dateihandle am Ende der Datei befindet und sedkeine Eingabe angezeigt wird . Der verbleibende Teil wird darin gepuffert dash. (Wenn das Skript länger als die Blockgröße von 8 kB wäre, würde der verbleibende Teil von gelesen sed.)
Bash hingegen sucht bis zum Ende des letzten Befehls zurück:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 36) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
...
lseek(0, -7, SEEK_CUR) = 29
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
Wenn die Eingabe von einer Pipe stammt, wie hier:
$ cat script.sh | bash
Das Zurückspulen ist nicht möglich, da Rohre und Muffen nicht suchbar sind. In diesem Fall fällt Bash zurück , um die Eingabe zu lesen ein Zeichen zu einem Zeitpunkt zu vermeiden overreading. ( fd_to_buffered_stream()ininput.c ) Ein vollständiger Systemaufruf für jedes Byte ist im Prinzip nicht sehr effektiv. In der Praxis denke ich nicht, dass das Lesen ein großer Aufwand sein wird, z. B. im Vergleich zu der Tatsache, dass die meisten Dinge, die die Shell tut, das Laichen ganz neuer Prozesse beinhalten.
Eine ähnliche Situation ist folgende:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
Die Subshell muss sicherstellen, dass readnur die erste neue headZeile gelesen wird, damit die nächste Zeile angezeigt wird . (Dies funktioniert auch mit dash.)
Mit anderen Worten, Bash unternimmt zusätzliche Anstrengungen, um das Lesen derselben Quelle für das Skript selbst und für von ihm ausgeführte Befehle zu unterstützen. dashnicht. Die zshund ksh93in Debian verpackten gehen mit Bash dazu.
sudo su: unix.stackexchange.com/questions/218169/…