長時間実行されているbash
インスタンス(screen
内 セッション)ループ内で複雑なコマンドのセットを実行しています(各ループはパイプ、リダイレクトなどを実行します)。
長いコマンドラインはターミナル内に記述されており、スクリプト内にはありません。これで、bashプロセスIDがわかり、ルートアクセス権があります。そのbash
内で実行されている正確なコマンドラインを確認するにはどうすればよいですか。 ?
例
bash$ echo $$
1234
bash$ while true ; do
someThing | somethingElse 2>/foo/bar |
yetAnother ; sleep 600 ; done
また、別のシェルインスタンスでは、PID1234内で実行されるコマンドラインを確認したいと思います。
bash$ echo $$
5678
bash$ su -
sh# cd /proc/1234
sh# # Do something here that will display the string
'while true ; do someThing | somethingElse 2>/foo/bar |
yetAnother ; sleep 600 ; done'
これは可能ですか?
編集#1
私が得たいくつかの答えの反例を追加します。
-
cmdline
の使用について/proc/PID
の下 :少なくとも私のシナリオでは、それは機能しません。簡単な例を次に示します。$ echo $$ 8909 $ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
別のシェルの場合:
$ cat /proc/8909/cmdline bash
-
ps -p PID --noheaders -o cmd
の使用 同様に役に立たない:$ ps -p 8909 --no-headers -o cmd bash
-
ps -eaf
役に立たない:$ ps -eaf | grep 8909 ttsiod 8909 8905 0 10:09 pts/0 00:00:00 bash ttsiod 30697 8909 0 10:22 pts/0 00:00:00 sleep 30 ttsiod 31292 13928 0 10:23 pts/12 00:00:00 grep --color=auto 8909
つまり、私が探しているのはORIGINALコマンドラインの出力ではありません。つまり、
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
。
承認された回答:
ストローを握っていることは知っていましたが、UNIXが失敗することはありません!
管理方法は次のとおりです。
bash$ gdb --pid 8909
...
Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libnss_files.so.2
0xb76e7424 in __kernel_vsyscall ()
次に、(gdb)
で プロンプトコマンドを実行しました。call write_history("/tmp/foo")
これにより、この履歴がファイル/tmp/foo
に書き込まれます。 。
(gdb) call write_history("/tmp/foo")
$1 = 0
次に、プロセスから切り離します。
(gdb) detach
Detaching from program: /bin/bash, process 8909
そして、gdb
を終了します 。
(gdb) q
そして確かに…
bash$ tail -1 /tmp/foo
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
後で簡単に再利用できるように、プロセスを自動化するbashスクリプトを作成しました。