次のスクリプトがあります
hello.sh
--------
while :
do
echo "hello"
sleep 20
done
上記のスクリプトを実行すると、スクリプトのPIDは2627になります。
root@localhost ~]# ./hello.sh &
[1] 2627
[root@localhost ~]#
別の端末でpsコマンドを実行すると、出力にスクリプト名が表示されなくなります。
[root@localhost ~]# ps -ef| grep 262[7]
root 2627 1582 0 19:19 pts/1 00:00:00 -bash
root 3427 2627 0 19:52 pts/1 00:00:00 sleep 20
[root@localhost ~]#
$$ は、スクリプトを実行するデフォルトシェルの PID です。私はスクリプト内で$$を入力してスクリプトのPIDを取得できることを知っていますが、それは私の意図ではありません。
バックグラウンドで長い間実行されているスクリプトがあり、誤って端末を閉じたと仮定すると、スクリプト名や他の方法でPIDをgrepする方法はありますか?
参考までに
[root@localhost ~]# echo $$
2586
[root@localhost ~]# ps -ef| grep 262[7]
root 2627 1582 0 19:19 pts/1 00:00:00 -bash
root 3657 2627 0 20:02 pts/1 00:00:00 sleep 20
[root@localhost ~]# ps -ef| grep bas[h]
root 1517 1513 0 18:43 pts/18 00:00:00 -bash
root 1582 1578 0 18:45 pts/1 00:00:00 -bash
root 2586 2581 0 19:18 pts/54 00:00:00 -bash
root 2627 1582 0 19:19 pts/1 00:00:00 -bash
[root@localhost ~]#
2586は、hello.shスクリプトを実行したプライマリシェルのPIDです。新しいシェルを作成し、その中でコマンドの実行を開始します。私はこれらの基本を知っています。これは重複した質問ではありません。これを理解するには、出力を見てください。
答え1
スクリプトとその名前がプロセスリストに表示されるようにするには、スクリプトに#! /bin/sh
適切なshe-bang行(または)を追加する必要があります。#! /bin/bash
例:
$ cat foo
sleep 10
$ ./foo &
[4] 4403
$ ps -q 4403
PID TTY TIME CMD
4403 pts/3 00:00:00 bash
$ cat bar
#! /bin/sh
sleep 10
$ ./bar &
[5] 4406
$ ps -q 4406
PID TTY TIME CMD
4406 pts/3 00:00:00 bar
そうでない場合、Linuxは次のディレクトリにスクリプト名を見つけることができます/proc/PID/fd
。
$ ./foo &
[2] 5125
$ ls -l /proc/5125/fd
total 0
lrwx------ 1 ahq ahq 64 Oct 22 17:57 0 -> /dev/pts/3
lrwx------ 1 ahq ahq 64 Oct 22 17:57 1 -> /dev/pts/3
lrwx------ 1 ahq ahq 64 Oct 22 17:57 2 -> /dev/pts/3
lr-x------ 1 ahq ahq 64 Oct 22 17:57 254 -> /tmp/foo
lrwx------ 1 ahq ahq 64 Oct 22 17:57 255 -> /dev/pts/3
4行目の254
fdは、実行中のスクリプトへのパスを指します。他のシェルと比較すると、これはまたはなどのbash
他のシェルです。fd
3
10
リバース検索を実行するためにも使用できますlsof /tmp/foo
。
答え2
Linuxでは、次のことができます。
grep -l hello.sh /proc/*/task/*/comm 2>/dev/null
...コマンドラインで "hello.sh"を使用してすべてのプロセス(実行時にpid 26560)を報告します。
/proc/26560/作業/26560/通信
stderrリダイレクトは、シェルがワイルドカードパスを拡張し、grepが読み取り/グレーピングのためにファイルを開くことを決定する時間の間に現在のプロセスの通信ファイル(/proc/self/task/$$/comm)が消えるgrepの苦情を取り除くことです。
2番目の「hello.sh」を実行すると、2つの結果が得られます。
$ ./hello.sh &
[2] 28328
$ grep -l hello.sh /proc/*/task/*/comm 2>/dev/null
/proc/26560/task/26560/comm
/proc/28328/task/28328/comm