2016-09-19 3 views
1

私は、ウィンドウの行末をチェックするシェルスクリプトを持っています。Bash "set -e"とネゲートされたリターンコード

set -e 

(! git ls-files | xargs grep -I $'\r') 

私は "!"コマンドの戻りコードを無効にします。 Grepはキャリッジリターンのあるファイルが見つかるとコード0を返し、 "!"戻りコードの値を無効にして1になり、スクリプトが終了します。 grep(no xargs)と一緒に使うと、これは括弧なしで動作します。 xargsが使用されると、否定は$?に応じて "echo $?" "1"が表示されますが、スクリプトは終了しません。コマンド全体をかっこで囲んだ後、期待通りに機能します。なぜかっこは必要ですか?

+0

"grep(no xargs)と一緒に使用すると、これはカッコなしで機能します。*"これは少し不明です。コードを表示してください。 – Leon

+0

_ "スクリプトは終了しません" _も不明です。 –

+2

['set -e'はgotchasでいっぱいです](http://mywiki.wooledge.org/BashFAQ/105)、bashコミュニティが非常に分かれていて、まったくいい考えです。 –

答えて

3

問題はxargsとは関係ありません。

bashの-eオプションはややこしいです。

-e終了直ちに、リスト、又は複合コマンド ( 単一単純なコマンドからなっていてもよい)パイプラインは、非ゼロで終了した場合 ステータス。 が失敗したコマンドが直ちに コマンドリストの一部である場合シェルは、while又はuntilキーワード以下&&で実行される任意 コマンドの一部をifまたはelif予約語以下の試験 の一部をを終了しませんまたは最終&&または||、 パイプライン内の任意のコマンドが、最後の、または次のコマンド 除く||リストコマンドの戻り値は !で反転されている場合。

のは、はるかに簡単な例を見てみましょう:「! true」の終了ステータスが非ゼロであったにも関わらず

$ cat exit_on_error_test.sh 
#!/bin/bash 

trap 'echo Interrupted because of an error' ERR 
set -e 

! true 
echo Exit status: $? 

$ ./exit_on_error_test.sh 
Exit status: 1 
$ 

ので、スクリプトが終了し、出力に値を実行させました終了ステータスのそれは、私たちが何らかの失敗コマンドを持っていなかったからです。ゼロ以外の終了コードは意図的な否定によるものです。

ただし、「! true」をかっこで囲むと、失敗する(複合)コマンドが導入されます。

$ cat exit_on_error_test.sh 
#!/bin/bash 

trap 'echo Interrupted because of an error' ERR 
set -e 

(! true) # This as a whole is now a failing (compound) command 
echo Exit status: $? 

$ ./exit_on_error_test.sh 
Interrupted because of an error 
$ 
0

set -eコマンドは(help setを参照)は、非ゼロの状態

でコマンドが終了した場合、直ちに

を終了するように指示します。

Bashでは、カッコ内の式はsubshell(サブプロセス)を作成します。これは1つのコマンドと同じように動作します。したがって、サブシェルがエラーコードで終了した場合、親スクリプトも終了します(-e設定のため)。

したがってgrep\r文字を検出した場合、サブシェルは非ゼロステータスで終了します。メインスクリプトもこのコードで終了します(set -eのため)。

質問への回答なぜかっこが必要ですか?は:grep\rという文字をgit制御下のファイルの1つに見つけると、おそらくメインスクリプトを終了したいからです。

関連する問題