Un script similaire, sans sudo
, mais des résultats similaires:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
Avec bash
, le reste du script va en entrée à sed
, avec dash
, le shell l'interprète.
En cours strace
d' exécution sur: dash
lit un bloc du script (huit Ko ici, plus que suffisant pour contenir l'intégralité du script), puis apparaît 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|...
Ce qui signifie que le descripteur de fichier est à la fin du fichier et sed
ne verra aucune entrée. La partie restante étant tamponnée à l'intérieur dash
. (Si le script était plus long que la taille de bloc de 8 Ko, la partie restante serait lue par sed
.)
Bash, par contre, cherche à revenir à la fin de la dernière commande:
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|...
Si l'entrée provient d'un tuyau, comme ici:
$ cat script.sh | bash
le rembobinage ne peut pas être fait, car les tuyaux et les prises ne sont pas recherchés. Dans ce cas, Bash revient à lire l'entrée un caractère à la fois pour éviter les surcharges. ( fd_to_buffered_stream()
ininput.c
) Faire un appel système complet pour chaque octet n'est pas très efficace en principe. Dans la pratique, je ne pense pas que les lectures seront un gros frais généraux par exemple par rapport au fait que la plupart des choses que le shell implique impliquent de nouveaux processus entiers.
Une situation similaire est la suivante:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
Le sous-shell doit s'assurer de read
ne lire que la première nouvelle ligne, de sorte que head
la ligne suivante soit visible. (Cela fonctionne dash
aussi avec .)
En d'autres termes, Bash va à des longueurs supplémentaires pour prendre en charge la lecture de la même source pour le script lui-même et pour les commandes exécutées à partir de celui-ci. dash
non. Le zsh
, et ksh93
empaqueté dans Debian vont avec Bash à ce sujet.
sudo su
: unix.stackexchange.com/questions/218169/…