Bash

sudo 將使用哪個 shell 來執行沒有 shebang 行的 shell 腳本

  • September 27, 2013

我的環境是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_BSHELLexecvp()定義/bin/sh/usr/include/paths.h. 這應該與使用envfind -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

引用自:https://unix.stackexchange.com/questions/92622