読者です 読者をやめる 読者になる 読者になる

絶品ゆどうふのタレ

ふと気づいたことを綴るだけのメモ

コンソールから切れたプロセスを標準出力につなげなおす

linux tips gdb shell

不慣れな環境を不意にいじった時にあるあるネタ

とりあえずー

とか言って勢いで書いたsetupスクリプトを実行してみたら意外と時間かかって、 ちょっと目を離した隙にsshの接続が切れちゃいました!

。。。ありますよね。ほんとよくありますよね。

そうなる予感はあったんだ

なんて後の祭りです。ふとした油断から、screenもnohupすらも使わずにやってしまって、こんなことに。 shellがHUPしなかったからプロセスは生きてるものの、ログが見れないから進行状況がわからない。

うまく行ってるのかどうかモヤモヤした気持ちのまま、プロセスが終わるのをじっと待つ。。。

まぁ実に切ないです。

こんな時、いつも思うこと。

このプロセスの出力、もっかいstdoutに繋げられたらいいのに。。。

はい。というわけでつなげましょう。 長い前座ですみません。

切り離したプロセスを用意

#!/bin/bash

while true; do
    date; sleep 5
done

上記のような hoge.sh というスクリプトを実行して、切り離します。

$ ./hoge.sh &!

この状態でコンソールを閉じると、ttyに繋がっていない状態のプロセスが生まれます。

$ ps ux|grep hoge |grep -v grep
yudoufu  15648  0.0  0.0  10680  1464 ?        SN   23:49   0:00 /bin/bash ./hoge.sh

$ ll /proc/15648/fd
total 0
lrwx------ 1 yudoufu yudoufu 64 Feb  5 23:58 0 -> /dev/pts/4 (deleted)
lrwx------ 1 yudoufu yudoufu 64 Feb  5 23:58 1 -> /dev/pts/4 (deleted)
lrwx------ 1 yudoufu yudoufu 64 Feb  5 23:49 2 -> /dev/pts/4 (deleted)
lr-x------ 1 yudoufu yudoufu 64 Feb  5 23:58 255 -> /home/yudoufu/hoge.sh

こいつを別の、まだ生きている(/dev/pts/5)に繋ぎ直してみます。

gdbでプロセスをつなげなおす

$ gdb -p 15648
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.

<snip>

32      ../sysdeps/unix/sysv/linux/waitpid.c: No such file or directory.
(gdb) p close(1)
$1 = 0
(gdb) p open("/dev/pts/5", 1)
$2 = 1
(gdb) p close(2)
$3 = 0
(gdb) p open("/dev/pts/5", 1)
$4 = 2
(gdb) detach
Detaching from program: /bin/bash, process 15648
(gdb) quit

これでstdout / stderrが生きてるttyの/dev/pts/5につながりました。

$ ll /proc/15648/fd
total 0
lrwx------ 1 yudoufu yudoufu 64 Feb  5 23:58 0 -> /dev/pts/4 (deleted)
lrwx------ 1 yudoufu yudoufu 64 Feb  5 23:58 1 -> /dev/pts/5
lrwx------ 1 yudoufu yudoufu 64 Feb  5 23:49 2 -> /dev/pts/5
lr-x------ 1 yudoufu yudoufu 64 Feb  5 23:58 255 -> /home/yudoufu/hoge.sh

/dev/pts/5のコンソールを見ると、5秒おきに時刻が表示されるようになったのを確認できるでしょう。

もちろん、openの指定先をコンソールにせずに、適当にtouchしておいたログファイルなどにすればファイルを出力先にできます。 リダイレクトを指定し忘れた場合の出力先の切り替えにも使えます。

困ったときにはお試しください。