dash
저는 debianstretch에서 실행 중이고 다음 명령( 및 ) 은 모두 bash
bash에 입력됩니다. 결코 사용자로 실행되지 않는
것 같습니다whoami
시험아래 코드와 같이 대시로 표시됩니다.
$ sudo dash << 'end'
> su test
> whoami
> end
root
$ sudo bash << 'end'
> su test
> whoami
> end
test
답변1
다음 예를 고려하십시오.
$ cat f
grep pos /proc/self/fdinfo/0
IFS= read -r var
echo A
echo B
printf '%s\n' "var=$var"
$ bash < f
pos: 29
B
var=echo A
$ dash < f
pos: 85
A
B
var=
보시다시피, 명령을 실행하면 grep
stdin의 위치는 파일의 끝이고 의 dash
명령 다음에 나오는 개행 문자 바로 뒤에 있습니다.grep
bash
명령 echo A
은 에 의해 실행되지만 dash
의 경우 bash
는 입력으로 주어진다 read
.
dash
명령을 실행하기 전에 전체 입력(실제로는 텍스트 블록)을 한 번에 한 줄씩 읽습니다 .bash
이렇게 하려면 bash
개행 문자를 지나 읽지 않도록 한 번에 한 바이트씩 읽어야 하지만 입력이 일반 파일인 경우( f
위의 내 파일의 경우와 같으며 문서에도 적용됩니다) 여기서) bash는 dash
파이프를 사용하는 동안 이를 임시 파일로 구현합니다 . Linux에서 볼 bash
수 있듯이 청크로 읽고 줄 끝으로 역추적하여 최적화합니다 .strace
$ strace -e 읽기,lseek bash < f [...] lseek(0, 0, SEEK_CUR) = 0 읽기(0, "grep pos /proc/self/fdinfo/0\nIFS"...,85) = 85 lseek(0, -56, SEEK_CUR) = 29 포지션: 29 [...] $ strace -e 읽기, lseek 대시 < f 읽기(0, "grep pos /proc/self/fdinfo/0\nIFS"...,8192) = 85 포지션: 85 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12422, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- 읽기(0,"",1) = 0 [...]
stdin이 터미널 장치인 경우 각각은 read()
터미널에서 전송한 라인을 반환하므로 일반적으로 bash
및 에서 유사한 동작을 볼 수 있습니다 dash
.
귀하의 경우에는 다음과 같이 할 수 있습니다.
sudo dash << 'end-of-script'
su test <<"end"
whoami
end
end-of-script
또는 더 나은:
sudo sh -c '
su test -c whoami
'
또는 더 나은 방법은 다음과 같습니다.
sudo -u test whoami
답변2
Bash와 Dash는 stdin의 입력을 다르게 처리합니다. 명령을 실행할 때( su
여기) Bash는 명령을 실행하게 한 줄 뒤의 stdin에서 시간 섹션 파이프에서 한 단어를 읽거나 거꾸로 살펴보는 방식으로 읽기 위치를 조심스럽게 유지합니다. 입력이 파일에서 오는지 확인하십시오. Dash는 신경 쓰지 않고 단지 전체 블록을 읽습니다.
이는 표준 입력과 그 안의 읽기 위치가 셸과 하위 프로세스 간에 공유되기 때문에 중요합니다.
따라서 Bash를 사용할 때 를 읽고 su test\nwhoami\n
첫 번째 개행 이후로 돌아가서 시작합니다. su
이는 이제 whoami\n
입력에 표시됩니다.
Dash의 경우 읽고 su test\nwhoami\n
시작 su
하고 입력이 표시되지 않고 종료된 다음 Dash가 시작됩니다 whoami
.
여기서도 같은 것을 볼 수 있습니다. Dash를 사용하면 date
명령을 실행하고 read
빈 입력을 얻는 반면 Bash를 사용하면 라인은 read
입니다 x
.
$ cat test.sh
read x
date
echo "variable x = '$x'"
$ cat test.sh | bash
variable x = 'date'
$ cat test.sh | dash
Sat Aug 24 12:25:23 EEST 2019
variable x = ''
내가 설명하면POSIX 설명sh
Bash의 신중한 행동이 필요하다는 점은 맞습니다. 반면 Dash의 여유로운 접근 방식은 이에 맞지 않습니다.
STDIN
[...] 쉘이 표준 입력을 사용하고 표준 입력도 사용하는 명령을 호출하는 경우, 쉘은 명령이 실행을 시작할 때 표준 입력 파일 포인터가 읽고 있는 명령 바로 뒤를 가리키는지 확인해야 합니다. 호출된 명령으로 읽을 문자가 셸에서 소비되는 방식으로 미리 읽어서는 안 됩니다.
그만한 가치가 있는 만큼 Busybox의 쉘은 Dash와 유사하게 작동하며, 제가 테스트한 다른 모든 쉘은 Bash의 기능을 수행합니다.