だるろぐ

だるいぶろぐです

openの -| と |-

気になった。
404 Blog Not Found:perl - open my $fh, "comand |"; # はモダンじゃない

書き込むときには'-|',読み込むときには'|-'を「ファイル名」として指定し、あとは実行したいコマンドと引数をリストとして渡す。


例えば外部コマンドを実行し、その結果を読み込むとき。

use strict;
use warnings;
use Data::Dumper;sub p {warn Dumper [@_];my @c = caller;print STDERR "  at $c[1]:$c[2]\n\n"}

open my $fh, '-|', qw/zcat memo.gz/ or die $!;
my @in;
while (my $l = <$fh>) {
    chomp $l;
    push @in, "__$l";
}
close $fh;

p \@in;
% zcat memo.gz
hoge
huga
foo
bar

% perl o.pl
$VAR1 = [
          [
            '__hoge',
            '__huga',
            '__foo',
            '__bar'
          ]
        ];
  at o.pl:13


これを

- open my $fh, '-|', qw/zcat memo.gz/ or die $!;
+ open my $fh, '|-', qw/zcat memo.gz/ or die $!;

こうすると。

% perl o.pl
hoge
huga
foo
bar
$VAR1 = [
          []
        ];
  at o.pl:13


memo.gzの中身が出力されているのは、外部コマンドが実行されたから。で、その出力先は$fhではなく、STDINに向いている。

% perldoc -f open

If the filename begins with '|', the filename is interpreted as a command to which output is to be piped, and if the
filename ends with a '|', the filename is interpreted as a command which pipes output to us.

ヤフー翻訳。

ファイル名が『|』で始まるならば、ファイル名は出力がパイプで送られることになっている命令と解釈されます、
そして、ファイル名が『|』で終わるならば、ファイル名は我々に出力をパイプで送る命令と解釈されます。

「我々」というのはperlだろう。つまり、ファイル名が『|』で始まれば出力はSTDINへ、『|』で終わればperlへ、それぞれ向かうようだ。

というわけで

冒頭の

書き込むときには'-|',読み込むときには'|-'を「ファイル名」として指定し、あとは実行したいコマンドと引数をリストとして渡す。

の、'-|'と'|-'が逆なのでは。