目次

38 プロセスのPTSを別のPTSへ出力

プロセスのファイルディスクリプタを別のPTSへ出力させる。

ファイルディスクリプタは通常、0:標準入力(stdin)、1:標準出力(stdout)、2:標準エラー出力(stderr)があって、
プロセスがファイルを開く場合は、3から割り当てられていく。

この1:標準出力(stdout)と2:標準エラー出力(stderr)を修正して別のPTSへ出力させます。

1. 1つのコンソールでシェルを実行

ただ5秒おきに時間を出力するだけのシェル

$ cat z.sh 
#!/bin/bash

while true; do
    date; sleep 5
done
$ bash z.sh

2. プロセスの状態確認

これで、プロセス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

4. もう一つのコンソールでpts確認

$ tty
/dev/pts/96

5. gdbでptsを変更

これで/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 

6. ファイルに出力する事も可能

出力するファイルだけ先に用意

$ 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