Аналогічний сценарій, без sudo
, але подібних результатів:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
З bash
, інша частина сценарію йде в якості вхідних даних sed
, з dash
, в тлумачить її оболонки.
Запуск strace
цих: dash
читає блок скрипту (тут вісім кБ, більше, ніж вимагає утримувати весь сценарій), а потім породжує 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|...
Що означає, що файл файлу знаходиться в кінці файлу, і sed
він не побачить жодного вводу. Інша частина буферується всередині dash
. (Якщо сценарій був більшим за розмір блоку 8 кБ, решта частина буде прочитана sed
.)
Bash, з іншого боку, намагається повернутися до кінця останньої команди:
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|...
Якщо вхід надходить з труби, як тут:
$ cat script.sh | bash
перемотування не можна проводити, оскільки труби та розетки не можна знайти. У цьому випадку Bash відновлює читання вводу по одному символу за раз, щоб уникнути його перечитання. ( fd_to_buffered_stream()
вinput.c
) Здійснення повного системного виклику для кожного байта в принципі не дуже ефективно. На практиці я не вважаю, що зчитування буде великим надмірним порівнянням, наприклад, з тим, що більшість речей оболонки передбачає нерест цілих нових процесів.
Схожа ситуація така:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
Підрозділ повинен переконатися, що read
він читає лише перший новий рядок, щоб head
побачити наступний рядок. (Це dash
теж працює .)
Іншими словами, Bash іде на додаткові тривалості, щоб підтримувати читання того самого джерела як для самого сценарію, так і для команд, що виконуються з нього. dash
не робить. І zsh
, і ksh93
упакований у Debian, йде разом із Bash.
sudo su
: unix.stackexchange.com/questions/218169/…