Аналогичный скрипт 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/…