
私は数日間スクリプトを実行してきました。 stdoutをstderrにリダイレクトしましたが、$HOME/mylog
stderrにリダイレクトしませんでした。なぜならそこには何もないと思ったからです。突然、stderrに何千もの行が表示され始め、タスクを一時停止しました。$HOME/myerr
スクリプトを再起動せずにこれからstderrをリダイレクトする方法はありますか?
ボックスへのsudoアクセス権があり、OS Xです。
dtoolsを使って何かをキャプチャできますか?
これまで、スクリプトが実行した操作を失い、最初から再開することはできません。ディスクの「メモリにオブジェクトをダンプ」し、プログラムを停止し、変数(ファイル記述子など)を編集します。また覆う新しい背景として?
答え1
そのインタプリタのプロセスをgdbに添付すれば可能だと思います。私はこのPerlの1行コードでそれを試しました
perl -e 'do { print "x\n"; sleep(1) } while(1)'
うまくいきますが、残念ながら同様のbashスクリプトでは機能しません。
まず、キャプチャしたい出力を持つプロセスのPIDを見つける必要があります。次に、別の端末で起動し、次のgdb
gdbコマンドを実行します。
attach PID
call close(2)
call open("/abs/olu/te/path/filename", 65, 384)
detach PID
それ以降に記録されたデータ全体にstderr
リダイレクトされます/abs/olu/te/path/filename
。
attach PID
プロセスをgdbに接続して停止します。call close(2)
stderr
プロセスのファイル記述子を閉じます(stdout
ファイル記述子は1です)。call open(...)
新しいファイルを開き、新しく作成されたファイル記述子に使用されなかった最小の整数を取得します。detach PID
プロセスを続ける
少なくとも私のコンピュータではそうです。最初の2行はPOSIXと互換性がありますが、3行目はそうではありません。
3行目の2番目と3番目のパラメータopen
はに記録されますman 2 open
。私の場合、65はopen
ファイルを書き込み専用に作成して開く必要があることを意味します(たとえば、でO_WRONLY | O_CREAT
定義されていますfcntl.h
)。 3番目のパラメータは、openに、ユーザーの読み取りおよび書き込み権限を持つファイルS_IWUSR | S_IRUSR
(定義済みsys/stat.h
)を生成するように指示します。そのため、お使いのマシンに適した値を直接把握する必要があるかもしれません。
答え2
これはおおよその答えであり、他の人がより良いことを願っています。ただし、他のアイデアがない場合は、gdbをリンクし、プロセスにいくつかのシステムコールを強制します。
(gdb) attach 12345 # target PID
(gdb) p close(2)
(gdb) p open("errfile", O_WRONLY)
(gdb) c