私の環境は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より多くの答えが可能です。