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 bash
dem Rest des Skripts geht als Eingabe sed
, mit dash
ihm, der Schale interpretiert.
Laufen strace
auf diesen: dash
Liest 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 sed
keine 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 read
nur die erste neue head
Zeile 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. dash
nicht. Die zsh
und ksh93
in Debian verpackten gehen mit Bash dazu.
sudo su
: unix.stackexchange.com/questions/218169/…