screen の backtick をいつか使う(mkfifo使用)
screen の backtick をいつか使う - l1o0の日記 でファイルの変更を読み取るのに、周期的にファイルを監視していたが、kazuhoのメモ置き場 を参考に、mkfifoを使えば簡単にプロセス間通信を実現できることがわかった。
mkfifo
mkfifoを使えばファイルをI/Fとして簡単にプロセス間通信を実現できる。例えば、以下のスクリプトを実行すると、
mkfifo.sh
#!/bin/sh fifo_file="/tmp/tmp$$.fifo" rm -f $fifo_file trap "rm -f $fifo_file; exit 1" 1 2 3 15 mkfifo -m 666 $fifo_file grep -i "init" $fifo_file | grep -v "grep" > result.txt & ps aux > $fifo_file rm -f $fifo_file
$ sh mkfifo.sh $ cat result.txt root 1 0.0 0.0 2112 740 ? Ss 02:38 0:01 init [5]
となる。バックグランド(つまり別プロセス)で動いているgrepと、fifoファイルを通して通信できていることがわかる。
ファイルのリダイレクト以外でも、オプションでファイル出力するタイプのコマンドでも同じことができる。
mkfifo_f.sh
#!/bin/sh fifo_file="/tmp/tmp$$.fifo" rm -f $fifo_file trap "rm -f $fifo_file; exit 1" 1 2 3 15 mkfifo -m 666 $fifo_file grep -i "open" $fifo_file > result.txt & strace -o $fifo_file ls rm -f $fifo_file
$ sh mkfifo_f.sh $ cat result.txt open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib/libselinux.so.1", O_RDONLY) = 3 open("/lib/i686/cmov/librt.so.1", O_RDONLY) = 3 open("/lib/libacl.so.1", O_RDONLY) = 3 open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3 open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3 open("/lib/i686/cmov/libpthread.so.0", O_RDONLY) = 3 open("/lib/libattr.so.1", O_RDONLY) = 3 open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3 open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
strace の -o オプションでファイルの出力先としてfifo ファイルを指定して、別プロセスで動いている grep にコマンド出力を渡している。
backtickスクリプトの変更
ということで、screen の backtick をいつか使う - l1o0の日記で使っていたperlスクリプトを以下のようにした。
#!/usr/bin/perl use strict; use warnings; use IO::File; use Path::Class qw(file); use POSIX qw(mkfifo); my $fifo = file( $ENV{HOME}, 'tmp', 'backtick.fifo' ); unlink $fifo; if ( !mkfifo( $fifo, 0666 ) ) { die "$!"; } while (1) { open my $fh, '<', $fifo or die "$fifo, $!"; while ( my $line = <$fh> ) { $line =~ s/\x0D?\x0A?$//; print $line, $/; (*STDOUT)->flush; } close $fh or die "$fifo, $!"; }