Bash
sudo 將使用哪個 shell 來執行沒有 shebang 行的 shell 腳本
我的環境是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
顯示 root 使用bash
,我是否遺漏了任何要點sudo
?
它使用Linux
_PATH_BSHELL
上execvp()
定義/bin/sh
為/usr/include/paths.h
. 這應該與使用env
或find -exec
例如執行時相同。它當然不應該使用使用者的登錄 shell。您在上面看到的事實
bash
是因為它bash
(您在其中輸入該命令行的 shell)試圖執行它,並且當它ENOEXEC
從它獲得錯誤程式碼execve
時決定用它自己來解釋它(在sh
兼容模式下)。
因為您不使用
-s
選項,所以sudo
將使用_PATH_BSHELL
(/usr/include/paths.h
在 Ubuntu 12.04 LTS 上定義)來設置$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