前の記事で、disownの素晴らしさを紹介したが、基本的に標準出力・標準エラーを諦めることになる。
調子の悪いHDDの丸ごとコピーとかだと、標準エラーを後で見たいので、なんとかならないかネット検索したところ、
gdbで接続して、dup2で標準出力・標準エラーをファイルに繋ぐなんて荒業を紹介している人がいた。
dup2なんてCプログラマじゃなきゃ使おうとも思わんな。
流れとしては、
- 特定のコマンドをdisownする。前の記事参照。
- プロセスIDを調べる
- 標準出力、標準エラーのファイルを用意する
- gdb -p で接続する
- dup2でファイルに接続する。
- デタッチ
- gdbを抜ける
うーん。絶対忘れる。
以下、サンプル。実際はcpとかでやると思うが今回は、標準出力と標準エラーが分かりやすいようにしている。
標準出力にはdateの結果、標準エラーにはerrorを5秒間隔で。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
$ bash -c 'while /bin/true ; do date ; echo error >&2;sleep 5; done ' 2014年 8月 12日 火曜日 12:16:25 JST error Ctrl-z # 一旦止める。 $ bg # バックグラウンドにする。 $ disown %1 # ここまででプロセスの準備OK。出力があるので、一度ログアウトして入り直した方がいいかも。 $ ps axfwww |grep while 8458 ? S 0:00 \_ bash -c while /bin/true ; do date ; echo error >&2;sleep 5; done # プロセスID確認 今回は、8458 $ touch /tmp/std{out,err} # ファイルを作る # # gdbで繋ぐ。ubuntuだと設定にもよるがsudoが必要。 # $ sudo gdb -p 8458 ###### snip ######## (gdb) p dup2(open("/tmp/stdout",1),1) # 標準出力を繋ぐ (gdb) p dup2(open("/tmp/stderr",1),2) # 標準エラーを繋ぐ (gdb) detach # デタッチ (gdb) quit # gdbを終了 # 確認する $ tail /tmp/stdout 2014年 8月 12日 火曜日 12:25:08 JST 2014年 8月 12日 火曜日 12:25:13 JST 2014年 8月 12日 火曜日 12:25:40 JST $ tail /tmp/stderr error error error |
うーん。非常にメンドイ。なるべくnohupを使いましょう。それか日常的にscreenを使いましょうってことですね。
ただ、考え方は非常に面白いので、覚えておくのはいいと思う。