ループ内で複雑な命令セットを実行する長期実行bash
インスタンス(セッション内)があります(各ループはパイプ、リダイレクトなどを実行します)。screen
長いコマンドラインは端末内に作成され、スクリプト内にはありません。これでbashプロセスIDを知り、rootアクセス権ができました。ここで実行された正確なコマンドラインをどのように表示できますかbash
?
bash$ echo $$
1234
bash$ while true ; do \
someThing | somethingElse 2>/foo/bar | \
yetAnother ; sleep 600 ; done
別のシェルインスタンスでPID 1234内で実行されているコマンドラインを表示したいと思います。
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
underの使用に関して/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
つまり、生のコマンドラインには出力がありません。これは私が探しているものです
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
。つまり。
答え1
私はジフラーでも持っていることを知っていますが、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
今後の再利用を容易にするために、次のように作成しました。バッシュスクリプト、プロセスを自動化します。
答え2
コマンドは画面上で実行され続けているため、その親bashはまだ履歴を再読み込みしていません。したがって、次のようになります。
- 画面に再接続
^Z
それから押してくださいup arrow
- ボーナス:コマンドを一重引用符で囲みます(
^A^A
- を使用します。なぜなら、screen(1)-と^E
)をナビゲートしてエコー+ファイルにリダイレクトするからです。 fg
コマンド実行の追求
いくつかの注意事項がありますが、ほとんどの場合これは十分に便利です。
答え3
私はあなたが自分の答えを見つけたことを知っていますが、これを行うことができない理由はありますか?
(set -x; for f in 1 2 3 4 ; do echo "$f"; sleep $f; done)
たぶん、実際のジョブの出力と現在実行されている行を示すbash出力を混在させることはできません。
また、FWIW、詳細が好きならset -o xtrace
。