가없는 유사한 스크립트 sudo
이지만 비슷한 결과 :
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
로 bash
, 스크립트의 나머지 부분에 입력으로 이동 sed
하여, dash
쉘 해석 그것.
strace
이것들에서 실행 : dash
스크립트 블록 (여기서 8 kB, 전체 스크립트를 보유하기에 충분한 것 이상)을 읽은 다음 생성합니다 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
. (스크립트가 8kB의 블록 크기보다 길면 나머지 부분을 읽습니다 sed
.)
반면 배시는 마지막 명령의 끝으로 되돌아갑니다.
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
데비안에서 패키지는이에 배쉬과 함께 할 것입니다.
sudo su
: unix.stackexchange.com/questions/218169/...