내 환경은 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
옵션을 사용하지 않기 때문에 sudo
(Ubuntu 12.04 LTS에 정의됨)을 사용하여 _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더 많은 답변이 가능합니다.