てきとうなメモ

本の感想とか技術メモとか

perlでパイプを使ってコマンドの入出力をopenした時のエラー処理

closeした時にエラーが返るのか

open(my $f, 'ls hoge |');
close $f or die $! ? "error on closing pipe" : "exit status = $?";
$ perl sample.pl
ls: hoge: No such file or directory
exit status = 256 at sample.pl line 2.

closeが失敗するのはパイプのcloseに失敗した場合とコマンドが失敗した場合とがあるが、$!が0かどうかで判別がつく。コマンドが失敗すると0になる。

$ perldoc -f close
...
            If the filehandle came from a piped open, "close" returns false if
            one of the other syscalls involved fails or if its program exits
            with non-zero status. If the only problem was that the program
            exited non-zero, $! will be set to 0. 

あと、$?はコマンドの戻り値が入っているがシェルの$?とは異なる

$ perldoc perlvar
...
    $CHILD_ERROR
    $?
...
            This is just the 16-bit status word returned by the
            traditional Unix "wait()" system call (or else is made up to look
            like it). Thus, the exit value of the subprocess is really ("$? >>
            8"), and "$? & 127" gives which signal, if any, the process died
            from, and "$? & 128" reports whether there was a core dump.

上位8ビットがコマンドの戻り値を表し、次の1ビットがコアダンプがあるかどうか、残り7ビットがどのシグナルで死んだか入っている。

ので、今回はコマンドの戻り値は1である