2016-08-28 2 views
3

私はいくつかの論理ANDコマンドを持っていて、中央にファイルを編集するperlコマンドがあります。perl - エラーファイルが見つからない場合は終了コード0、なぜコード1にすることができますか?

echo before && \ 
perl -pe 's/foo/bar/g' -i qux && \ 
echo after 

ファイルはperlがで死ぬんだろうが存在しない場合は、「開けませんquxすることができます。そのようなファイルやディレクトリを」しかし、エラーコードは0です。コマンドを続行したくないので、それは問題です。言い換えれば、 'after'は、ファイルが存在しない場合は印刷しないでください。なぜそれが起こっているのですか?それをどうやって止めることができますか?

+1

あなたはちょうど 'echo && test -f qux && ...' – dsm

+0

@dsm yeahは良い回避策のようです、ありがとう – newguy

+1

インタープリタ(Perl)が(1行)それが実行されたプログラム。成功(0)以外のものを返す理由はありません。 1つのライナーの代わりにスクリプトを呼び出す場合は、それを「終了1」にすることができます。 – zdim

答えて

4

あなたはperl -pe ... < fileの代わりperl -pe ... fileを使用する場合があります。この場合、たとえファイルが存在しない場合でも、シェルはperlを起動しなくてもすでに不平を言っているでしょう。しかし、スイッチ-iと一緒に使用することはできません。

それとも-iスイッチを使用したいので、あなたは、ファイルがそれを使用する前に、書き込み可能であることを確認することがあります。これは、quxがファイルと書き込み可能の両方であることをチェックするのではなく、これらのうちの1つだけでは不十分である(おそらく1つは読み取り可能であるかどうかをチェックする必要があるかもしれない)ためです。 perl自体はperlによって実行されるコードがなかった場合でも、成功したので、

[ -f qux ] && [ -w qux ] && perl -pe ... -i qux 
+0

これは、ファイルをインプレースで変更するのではなく、出力がSTDOUTに書き込まれるため、Perlのセマンティクスを変更します。 –

+0

@DaveSherohman:そうです、私は '-i'スイッチに気付かなかった。私はこの問題に対処する別の方法を追加しました。 –

2

OK、そう...

質問へのコメントで述べたように、0とperl終了理由があります。障害が発生して終了するには、ファイルを開くことができない場合には、die(明示的にはexitのステータスが0以外)にする方法を見つける必要があります。

しかし、perl -pは、1行の周りにループをラップするので、すべての行でテストを繰り返す必要はありませんか?はい、できます! perldoc perlrunは、BEGINENDブロックを使用して、ループ実行の前後に制御できることを示しています。

しかし、まだファイルが正常に開かれたかどうかを判断する方法が必要です。これを行うには、<>によって使用されるファイルハンドルの名前を知る必要があります。perldoc perlvarは、ARGVと呼ばれています。

しかしARGVが、それが読み出さだときのみ(確実に)魔法であるので、我々はそれはファイルが欠落している場合でも、定義された常にだ、それが原因で(私の迅速なテストで)定義されたのかどうかをテストすることはできません。だから我々はそれから読む必要があります。そして、最初の行が失われます。しかし、これはファイルの先頭に戻ってseekで簡単に修正されています。

TL; DR、すべてその結論:これはまだ100%完璧ではないこと

echo before && \ 
perl -pe 'BEGIN { exit 1 unless <> ; seek ARGV,0,0 } s/foo/bar/g' -i qux && \ 
echo after 

注意。ファイルが存在する場合はdieになりますが、空です。 defined <>をチェックしてもこの欠陥が修正されず、<> ; die unless ARGVにすると、<>がファイルが存在しない場合はSTDINから読み取られます。空のファイルを正しく検出する方法を誰かが持っているなら、私はそれについて聞くことに非常に興味があります!

+2

ああ、それは私を逃れました。私は '-e'だけで短い一行をまとめましたが、これは良いです。私のテストでは、 'BEGIN {exit-1なら-f $ ARGV [0]または-z $ ARGV [0]} 'が両方のケースを処理します。もっと長くても、それから「求める」必要はありません。 – zdim

+1

'BEGIN {' '' '' eof() ''(http://perldoc.perl.org/functions/eof.html)'} ' – Zaid

+0

とても良い、@ Zaid!私は、その魔法を持っていることを知らなかった。残念ながら、空のファイルと不足しているファイルを区別することはできません。 @zdimが示唆しているように、Perlコード内のファイルテストを明示的に使用しなければ、そうする方法がないように見えるでしょう。 –

関連する問題