~에 따르면스도(8):
Process model
sudo는 명령을 실행할 때 fork(2)를 호출하고 위에서 설명한 대로 실행 환경을 설정한 다음 하위 프로세스에서 execve 시스템 호출을 호출합니다.
또한 포크된 하위 프로세스가 sh
.
따라서 명령이 일부 bash 관련 명령(예: source
해당 명령) 을 포함하는 bash 스크립트인 경우 sh
올바르게 실행되지 않습니다. 예를 들어:
% 고양이/tmp/wibble 뭔가 소스 % ls -l /tmp/wibble -rwxr-xr-x 사용자 1명 user17 8월 24일 08:32 /tmp/wibble % 비밀번호 루트 가져오기 루트:x:0:0:루트:/루트:/bin/bash % /tmp/스윙 /tmp/wibble: 1: /tmp/wibble: 소스: 찾을 수 없음 % /bin/bash /tmp/wibble ~ [pts/3.4028.1] /tmp/wibble: 1행: 무엇인가: 해당 파일이나 디렉터리가 없습니다. % /bin/dash /tmp/wibble /tmp/wibble: 1: /tmp/wibble: 소스: 찾을 수 없음 % /bin/sh /tmp/wibble /tmp/wibble: 1: /tmp/wibble: 소스: 찾을 수 없음 %에코 $SHELL /bin/zsh % sudo /tmp/wibble /tmp/wibble: 1: /tmp/wibble: 소스: 찾을 수 없음 % sudo -s /tmp/wibble /tmp/wibble: 1: /tmp/wibble: 소스: 찾을 수 없음 % sudo -i /tmp/wibble /tmp/wibble: 1행: 무엇인가: 해당 파일이나 디렉터리가 없습니다. % 내보내기 SHELL=/bin/bash % sudo /tmp/wibble /tmp/wibble: 1: /tmp/wibble: 소스: 찾을 수 없음 % sudo -s /tmp/wibble /tmp/wibble: 1행: 무엇인가: 해당 파일이나 디렉터리가 없습니다. % sudo -i /tmp/wibble /tmp/wibble: 1행: 무엇인가: 해당 파일이나 디렉터리가 없습니다. %
-s
일반적으로 이 문제를 해결하기 위해 이전 예와 같이 옵션을 추가할 수 있지만 기본값이 사용되는 sudo
이유를 알고 싶습니다 . 이것을 다른 쉘로 구성할 수 있습니까?sudo
sh
답변1
스크립트가 #!
적절한 -line으로 시작하는지 확인하세요.
스크립트가 실행 가능하고 예를 들어 다음으로 시작하는 경우
#!/bin/bash
(또는 시스템의 모든 경로 bash
) 뒤에 스크립트가 옵니다.~ 할 것이다/bin/bash
sudo script
를 입력하면 Python 스크립트가 /usr/bin/python
첫 번째 줄이 로 해석되는 것처럼 으로 해석됩니다 #!/usr/bin/python
.
sh
쉘 bash
이나 다른 쉘에 대한 질문은 여기서 흥미롭지 않습니다. 일반적으로 말하면,각 유형의 셸에는 상호 배타적인 스크립팅 언어가 있다고 가정합니다.그리고 #!
-line을 사용하여 스크립팅할 인터프리터를 정확하게 지정하세요. 예를 들어, POSIX 구문과 구문만을 사용하여 이식 가능한 스크립트를 작성하는 경우 사용 #!/bin/sh
하고 POSIX 셸을 확장하는 배열이나 기타 항목을 #!/bin/bash
사용하는 경우 를 사용합니다.bash
텍스트 파일 #!
이 /bin/sh
. 이것은 와는 아무 관련이 없습니다 sudo
.
업데이트된 질문에서 -line 없이 스크립트에 대한 여러 호출을 표시합니다 #!
. 인터프리터가 source
명령( source: not found
)을 이해하지 못하거나 파일( something: No such file or directory
)을 찾을 수 없기 때문에 모두 실패합니다.
요약하자면, 스크립트의 인터프리터를 지정하려면 항상 -line을 사용하세요 #!
.
source
또한: 를 사용할 때는 ./something
.$PATH
관련된:
답변2
업데이트: 질문이 크게 수정되었으므로 내 대답이어야 합니다.
"스크립트"로 간주되는 것에 대한 표준 정의가 없다는 것을 발견했지만 단순히 명령 목록을 포함하는 파일이라도 쉘에 의해 실행되는 한 "스크립트"가 될 수 있습니다. 따라서 스크립트 상단에 쉘이 지정되지 않으면 기본 동작(sh)이 채택된다는 점에 주의해야 합니다.
이전 답변: bash가 현재 시스템에 없으면 bashism을 이해할 수 없기 때문에 스크립트가 실패해야 합니다
. 실험을 해보자!sh
~/Downloads/test$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 8月 31 2016 /bin/sh -> dash
sh
먼저, 아닌지 확인하세요 bash
. 을 사용하여 다른 bash 스크립트를 호출
bash.sh
합니다 .bash
sudo
:~/Downloads/test$ cat bash.sh
#!/bin/bash
sudo ./sudo_bash.sh
dash.sh
((i++))
귀하의 말에 따라 bashism이 실패해야 함 을 나타내는 대시 스크립트입니다 .
:~/Downloads/test$ cat dash.sh
#!/bin/sh
i=0
((i++))
echo $i
확인하자
:~/Downloads/test$ ./dash.sh
./dash.sh: 4: ./dash.sh: i++: not found
0
:~/Downloads/test$
아름답게 실패했습니다. 이제 sudo_bash.sh
bash 스크립트입니다. sudo 명령을 사용하여 bash.sh에서 실행하겠습니다. 말씀하신 대로 실제로 분기된 경우에도 sh
실패해야 합니다.
:~/Downloads/test$ cat sudo_bash.sh
#!/bin/bash
i=0
((i++))
echo $i
:~/Downloads/test$ ./bash.sh
[sudo] password for cs-server:
1
:~/Downloads/test$
실행 성공. 이는 새로운 환경을 사용할 수 없다는 것을 증명합니다 /bin/sh
.
I'd like to know why sudo uses sh as default.
역사적으로 첫 번째 셸은 sh였으므로 호환성을 위해 이름이 유지됩니다.
Is it so that it can be configured to other shells?
물론 sh의 심볼릭 링크만 변경하면 됩니다.
:~/Downloads/test$ cat text_file
i=0
((i++))
echo $i
:~/Downloads/test$ chmod +x text_file
:~/Downloads/test$ sudo ln -sf bash /bin/sh
:~/Downloads/test$ sudo ./text_file
1
:~/Downloads/test$ sudo ln -sf dash /bin/sh
:~/Downloads/test$ sudo ./text_file
./text_file: 2: ./text_file: i++: not found
0