プロセスのファイルディスクリプタを別のPTSへ出力させる。
ファイルディスクリプタは通常、0:標準入力(stdin)、1:標準出力(stdout)、2:標準エラー出力(stderr)があって、
プロセスがファイルを開く場合は、3から割り当てられていく。
この1:標準出力(stdout)と2:標準エラー出力(stderr)を修正して別のPTSへ出力させます。
ただ5秒おきに時間を出力するだけのシェル
$ cat z.sh
#!/bin/bash
while true; do
date; sleep 5
done
$ bash z.sh
これで、プロセスID(24870)と現在の出力先が/dev/pts/94であることがわかる。
$ ps auxw| grep z.sh matsui 24870 0.0 0.0 106108 1156 pts/94 S+ 21:46 0:00 /bin/bash ./z.sh $ ll /proc/24870/fd/ total 0 lrwx------ 1 matsui users 64 May 1 21:47 0 -> /dev/pts/94 lrwx------ 1 matsui users 64 May 1 21:47 1 -> /dev/pts/94 lrwx------ 1 matsui users 64 May 1 21:47 2 -> /dev/pts/94 lr-x------ 1 matsui users 64 May 1 21:47 255 -> /home/matsui/z.sh
$ tty /dev/pts/96
これで/dev/pts/96に出力されるようになります。
gdbが入ってない場合は、yumでインストール: yum install gdb
$ gdb
(gdb) attach 24870
(gdb) p close(1)
$1 = 0
(gdb) p open("/dev/pts/96",1)
$2 = 1
(gdb) p close(2)
$3 = 0
(gdb) p open("/dev/pts/96",2)
$4 = 2
(gdb) detach
出力するファイルだけ先に用意
$ touch /tmp/log
これで/tmp/logに出力されます。
$ gdb
(gdb) attach 24870
(gdb) p close(1)
$1 = 0
(gdb) p open("/tmp/log",1)
$2 = 1
(gdb) p close(2)
$3 = 0
(gdb) p open("/tmp/log",2)
$4 = 2
(gdb) detach