@kyanny's blog

My life. Opinions are my own.

eshell のパイプ

eshell では input redirection が使えない (perl ./hoge.pl < file とかできない) のだけど、 cat file | perl ./hoge.pl で代用できるよ、というのが知られている。

けどこれも厳密にはふつうの shell とはちょっと違うようだ。

#!/usr/local/bin/perl
use strict;
use Test::Simple tests => 1;

ok -t STDIN;

1;

こんなスクリプトを用意する。 pipe か input redirection で標準入力に何か渡されてきた場合このテストは失敗するはず。でも・・・

  • bash
bash-3.2$ cat file | perl ./pipe.pl                                                                                  
1..1                                                                                                                 
not ok 1                                                                                                             
#   Failed test at ./pipe.pl line 5.                                                                                 
# Looks like you failed 1 test of 1.

bash-3.2$ perl ./pipe.pl < file                                                                                      
1..1                                                                                                                 
not ok 1                                                                                                             
#   Failed test at ./pipe.pl line 5.                                                                                 
# Looks like you failed 1 test of 1.

bash-3.2$ perl ./pipe.pl                                                                                             
1..1                                                                                                                 
ok 1 
  • eshell
$ cat file | perl ./pipe.pl     # ←これは失敗して欲しいところだが・・・
1..1
ok 1

$ perl ./pipe.pl 
1..1
ok 1


という、割とどうでもいい話でした。

ちなみに何故こんなことを調べたかというと

ちょっとしたスクリプトがあって、使い方がよくわからないときに、単に perl ./script.pl とだけ実行したら Usage を出力して終了してくれるととても使いやすいよなー、と思うことが多くて、そういうデフォルトでは何もしないスクリプトをなるべく自分では書くように心がけている。のだけど、 while (<>) {} とかで標準入力からのデータをフィルタリングするようなスクリプトはふつうに書くと、標準入力を待つので引数なにもなしで実行した場合に Usage を出して終了、という挙動ができない。ので、標準入力があるかないかを判別したかった、というわけ。

この「デフォルトでは何もしない」は「Usage がちゃんと書いてある」場合にはとても良いと思う。冗長なので UNIX 的ではないかもしれない。けどファイルに書いておくからには再利用するつもりだったのだろうし、再利用するときにいちいちソースを読み直さなきゃ使い方もわからないってのは不親切だし非効率だ。最初に簡単なドキュメントも含めて書いておいて、次から使うときは何も考えずに、ファイル名と置き場所以外は何も覚えておく必要なく、すぐ使い方がわかって使えるべきだと思う。言葉の説明なんて一切いらない。ただ、コマンドラインからの実行例が $ perl ./script.pl --opt=XXXX < file みたいに書いてあるだけで十分。こういう姿勢というか考え方って、身近な例でいうと lwp-request とかから学んだのかもしれない。