내 환경은 Ubuntu 12.04 LTS이고 sudo
버전은 1.8.3p1입니다.
먼저 일반 사용자로 로그인합니다.
$ whoami
fin
$ cat /etc/passwd | grep -i "root\|fin"
root:x:0:0:root:/root:/bin/bash
fin:x:1000:1000:This is a normal user:/home/fin:/bin/bash
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 30 2012 /bin/sh -> dash
$ ls -l /bin/bash
-rwxr-xr-x 1 root root 920788 Apr 3 2012 /bin/bash
$ echo $SHELL
/bin/bash
$ ps | grep "$$" | awk '{ print $4 }'
bash
$ ls -l ./test.sh
-rwxr-xr-x 1 fin fin 37 Sep 27 16:46 test.sh
$ cat ./test.sh
ps | grep "$$" | awk '{ print $4 }'
$ ./test.sh
bash
$ sudo ./test.sh
sh
나는 루트가 를 사용한다는 것을 보여주므로 bash
마지막 출력도 다음과 같아야 한다고 생각합니다 . 에 대한 요점이 누락되었습니까 ?/etc/passwd
bash
sudo
답변1
Linux에서 와 같이 정의된 것과 _PATH_BSHELL
유사 하게 사용됩니다 . 이는 또는 예를 들어 실행될 때와 동일해야 합니다 .execvp()
/bin/sh
/usr/include/paths.h
env
find -exec
확실히 사용자의 로그인 셸을 사용해서는 안 됩니다. bash
위에서 보고 있는 사실은 bash
이를 실행하려고 시도하는 것(해당 명령줄에 입력한 셸)이 ENOEXEC
오류 코드를 받으면 대신( 호환 모드 execve
에서) 자체적으로 해석하기로 결정하기 때문입니다.sh
답변2
-s
옵션을 사용하지 않기 때문에 (Ubuntu 12.04 LTS에서 정의된 ) sudo
을 사용하여 실행을 설정합니다 . 소스 코드 살펴보기 :_PATH_BSHELL
/usr/include/paths.h
$SHELL
sudo
/* Stash user's shell for use with the -s flag; don't pass to plugin. */
if ((ud->shell = getenv("SHELL")) == NULL || ud->shell[0] == '\0') {
ud->shell = pw->pw_shell[0] ? pw->pw_shell : _PATH_BSHELL;
}
-s
옵션을 사용하는 경우 다음 대신에 sudo
옵션을 사용합니다 .$SHELL
_PATH_BSHELL
$ cat ./test.sh
ps | grep "$$" | awk '{ print $4 }'
$ ./test.sh
bash
$ sudo -s ./test.sh
bash
답변3
커널은 바이너리 실행 가능 이미지만 실행할 수 있습니다. 그렇다면 스크립트는 어떻게 실행되나요? 결국 my_script_without_shebang
쉘 프롬프트에 입력해도 오류가 발생하지 않습니다 ENOEXEC
. 스크립트 실행은 커널이 아니라 셸에서 수행됩니다. 셸의 실행 코드는 일반적으로 다음과 같습니다.
/* try to run the program */
execl(program, basename(program), (char *)0);
/* the exec failed -- maybe it is a shell script without shebang? */
if (errno == ENOEXEC)
execl ("/bin/sh", "sh", "-c", program, (char *)0);
Shebang 없이 더미 쉘 스크립트를 추적하여 이를 확인할 수 있습니다.
cat > /tmp/foo.sh <<EOF
echo
EOF
chmod u+x /tmp/foo.sh
strace /tmp/foo.sh 2>&1 | grep exec
execve("/tmp/foo.sh", ["/tmp/foo.sh"], [/* 28 vars */]) = -1 ENOEXEC (Exec format error)
그런 다음 Stephane이 설명한 대로 실행이 진행됩니다. 기본 셸이 사용됩니다(위 코드 조각에서는 하드 코딩되어 있습니다).이 좋은 UNIX FAQ더 많은 답변을 드릴 수 있습니다.