sh 대신 sudo 포크 bash를 만드는 방법은 무엇입니까?

sh 대신 sudo 포크 bash를 만드는 방법은 무엇입니까?

~에 따르면스도(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이유를 알고 싶습니다 . 이것을 다른 쉘로 구성할 수 있습니까?sudosh

답변1

스크립트가 #!적절한 -line으로 시작하는지 확인하세요.

스크립트가 실행 가능하고 예를 들어 다음으로 시작하는 경우

#!/bin/bash

(또는 시스템의 모든 경로 bash) 뒤에 스크립트가 옵니다.~ 할 것이다/bin/bashsudo script를 입력하면 Python 스크립트가 /usr/bin/python첫 번째 줄이 로 해석되는 것처럼 으로 해석됩니다 #!/usr/bin/python.

shbash이나 다른 쉘에 대한 질문은 여기서 흥미롭지 않습니다. 일반적으로 말하면,각 유형의 셸에는 상호 배타적인 스크립팅 언어가 있다고 가정합니다.그리고 #!-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합니다 .bashsudo

:~/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.shbash 스크립트입니다. 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

관련 정보