bash
というスクリプトがありますtest.sh
。 shebangを使用するstartproc
と、ファイルは次のようになります。#!/usr/bin/env bash
test.sh
/proc/<PID>/cmdline
SERVER:~ # cat /proc/29481/cmdline
bash/root/user/test.shSERVER:~ #
SERVER:~ #
#!/bin/bash
Shebang行を:に変更すると、/proc/<PID>/cmdline
ファイルは次のようになります。
SERVER:~ # cat /proc/29729/cmdline
/bin/bash/root/user/test.shSERVER:~ #
SERVER:~ #
この動作の原因は何ですか?ファイルの内容は/proc/<PID>/cmdline
スクリプトshebangによって異なりますか?問題は、以前のオプションを使用してもcheckproc
サービスを検出できないことkillproc
です。私はopenSUSE 11.4と。startproc
test.sh
sysvinit-tools-2.88-37.47.1.x86_64
ベストアンサー1
はい、実行されたシステムコールcmdline
によって、正規化されたパスはパス検索に表示されるパスとは異なる場合があります。exec*
env(1)
bash-4.1$ cat aaa
#!/bin/bash
xxd /proc/$$/cmdline
bash-4.1$ cat bbb
#!/usr/bin/env bash
xxd /proc/$$/cmdline
bash-4.1$ ./aaa
0000000: 2f62 696e 2f62 6173 6800 2e2f 6161 6100 /bin/bash../aaa.
bash-4.1$ ./bbb
0000000: 6261 7368 002e 2f62 6262 00 bash../bbb.
bash-4.1$
strace
詳細を表示:
bash-4.1$ strace ./aaa 2>&1 | grep exec
execve("./aaa", ["./aaa"], [/* 57 vars */]) = 0
bash-4.1$ strace ./bbb 2>&1 | grep exec
execve("./bbb", ["./bbb"], [/* 57 vars */]) = 0
execve("/sbin/bash", ["bash", "./bbb"], [/* 57 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/sbin/bash", ["bash", "./bbb"], [/* 57 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/local/sbin/bash", ["bash", "./bbb"], [/* 57 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/bash", ["bash", "./bbb"], [/* 57 vars */]) = 0
bash-4.1$
Linux専用スクリプトの場合、場所は変更されないことがあります(例外:、bash
他の場所を含むbash
一種のソフトウェアライブラリがあります)。したがって、正規化されたパスを使用するのが最適です。これにより、env(1)
パスを検索する際の混乱を避け、initツールとの互換性を得ることができます。