44

実行を停止したはずのスクリプトがいくつかありますが、永遠にぶらぶらしています。彼らがSTDOUTとSTDERRに何を書いているのかを読みやすい方法で理解できる方法はありますか?

たとえば、次のことを試みました。

$ tail -f /proc/(pid)/fd/1

しかし、それは実際には機能しません。とにかく遠回りでした。

他のアイデアはありますか?

straceそれ自体は非常に冗長で、これを見るには判読できません。

注: 私は彼らのアウトプットだけに関心があり、他のことには関心がありません。私は自分で他のことを理解することができます。この質問は、実行中のプロセスの開始後に stdout および stderr にアクセスすることにのみ焦点を当てています。

4

8 に答える 8

44

Jauco の回答を編集することは許可されていないため、私にとって有効な完全な回答を提供します (Russell のページは、STDOUT のファイル記述子 1 を閉じると、次のcreat呼び出しで FD 1 が開かれるという保証されていない動作に依存しています。

したがって、次のような単純なエンドレス スクリプトを実行します。

import time

while True:
    print 'test'
    time.sleep(1)

test.py に保存し、実行します

$ python test.py

PID を取得します。

$ ps auxw | grep test.py

次に、添付しgdbます。

$ gdb -p (pid)

そしてfd魔法を行います:

(gdb) call creat("/tmp/stdout", 0600)
$1 = 3
(gdb) call dup2(3, 1)
$2 = 1

tail /tmp/stdoutこれで、STDOUT に出力されていた出力を確認できます。

于 2008-10-30T11:57:31.310 に答える
10

「gdb メソッド」をまとめていくつかの追加機能を追加する新しいユーティリティがいくつかあります。私が今使っているのは「reptyr」(「Re-PTY-er」)と呼ばれるものです。STDERR/STDOUT を取得することに加えて、プロセスの制御端末を実際に変更します (以前に端末に接続されていなかった場合でも)。

これを使用する最善の方法は、screen セッションを開始し、それを使用して実行中のプロセスを screen 内の端末に再接続し、安全に切り離して後で戻ることができるようにすることです。

一般的なディストリビューションにパッケージ化されています (例: 'apt-get install reptyr')。

http://onethingwell.org/post/2924103615/reptyr

于 2012-09-11T01:07:09.350 に答える
9

GDB メソッドの方が優れているように見えますが、 でこれを行うこともできますstrace

$ strace -p <PID> -e write=1 -s 1024 -o file

のマニュアルページからstrace:

   -e write=set
               Perform a full hexadecimal and ASCII dump of all the
               data written to file descriptors listed in the spec-
               ified  set.  For example, to see all output activity
               on file descriptors 3 and 5 use -e write=3,5.   Note
               that  this is independent from the normal tracing of
               the write(2) system call which is controlled by  the
               option -e trace=write.

これは必要以上に (16 進数部分) を出力しますがsed、簡単に出力できます。

于 2008-10-30T19:29:30.260 に答える
7

それがうまくいくかどうかはわかりませんが、gdbを使用する方法を説明しているページを少し前に読みました

于 2008-10-30T10:02:12.057 に答える
6

strace を使用し、16 進出力をデコードしてテキストをクリアしました。

PID=some_process_id
sudo strace -f -e trace=write -e verbose=none -e write=1,2 -q -p $PID -o "| grep '^ |' | cut -c11-60 | sed -e 's/ //g' | xxd -r -p"

このコマンドを他の回答から組み合わせました。

于 2012-08-09T21:58:25.620 に答える
4

strace-ewriteだけで(接尾辞ではなく)出力がはるかに少なくなり=1ます。また、GDB メソッドである IMO よりも少し単純です。

これを使用して、既存の MythTV エンコーディング ジョブの進行状況を確認しました (sudoエンコーディング プロセスを所有していないため)。

$ ps -aef | grep -i handbrake
mythtv   25089 25085 99 16:01 ?        00:53:43 /usr/bin/HandBrakeCLI -i /var/lib/mythtv/recordings/1061_20111230122900.mpg -o /var/lib/mythtv/recordings/1061_20111230122900.mp4 -e x264 -b 1500 -E faac -B 256 -R 48 -w 720
jward    25293 20229  0 16:30 pts/1    00:00:00 grep --color=auto -i handbr

$ sudo strace -ewrite -p 25089
Process 25089 attached - interrupt to quit
write(1, "\rEncoding: task 1 of 1, 70.75 % "..., 73) = 73
write(1, "\rEncoding: task 1 of 1, 70.76 % "..., 73) = 73
write(1, "\rEncoding: task 1 of 1, 70.77 % "..., 73) = 73
write(1, "\rEncoding: task 1 of 1, 70.78 % "..., 73) = 73^C
于 2011-12-30T23:46:50.973 に答える
3

リダイレクトを使用できます ( https://github.com/jerome-pouiller/reredirect/ )。

タイプ

reredirect -m FILE PID

出力 (標準およびエラー) は FILE に書き込まれます。

reredirectREADMEは、プロセスの元の状態を復元する方法、別のコマンドにリダイレクトする方法、または stdout または stderr のみをリダイレクトする方法についても説明します。

于 2014-10-14T14:28:03.343 に答える
1

あなたはあなたのオペレーティングシステムを述べていませんが、私は突き刺して「Linux」と言うつもりです.

stderr と stdout に何が書き込まれているのかを確認しても、おそらく役に立たないでしょう。便利な場合は、スクリプトを開始する前に tee(1) を使用して、stderr と stdout のコピーを取得できます。

ps(1) を使用して wchan を探すことができます。これにより、プロセスが何を待っているかがわかります。strace の出力を見ると、出力の大部分を無視して、最後の (ブロックされた) システム コールを特定できます。ファイル ハンドルに対する操作である場合は、出力をさかのぼって、基になるオブジェクト (ファイル、ソケット、パイプなど) を特定できます。そこから答えが明らかになる可能性があります。

また、コアをダンプするシグナルをプロセスに送信し、デバッガーとコア ファイルを使用してスタック トレースを取得することもできます。

于 2008-10-30T10:22:58.710 に答える