2016-09-19 3 views
1

У меня есть сценарий оболочки, который проверяет окончание строк Windows.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.

-e вариант bash немного сложный.

-e Выход немедленно, если трубопровод (который может состоять из одного простой команды), в списке , или команда соединения , выходит с ненулевым статус. Оболочка не выходит, если команда, которая не может является частью списка команд сразу после while или until ключевого слова, часть теста следующих за if или elif зарезервированные слова, часть любого выполненной команды в && или || списка, за исключением команды после окончательного && или ||, любой команды в трубопроводе, но последний, или если возвращаемое значение командного является инвертируются с !.

Давайте посмотрим на более простом примере:

$ 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» был отличен от нуля, то сценарий было разрешено работать до конца и вывода значения статуса выхода. Это потому, что у нас не было никакой команды с ошибкой - ненулевой код выхода был вызван преднамеренным отрицанием.

Однако, если мы заключим в круглые скобки «! 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 (подпроцесс), который работает как одна команда. Таким образом, если подоболочка выходит с кодом ошибки, также выводится родительский скрипт (из-за установки -e).

Так что, если grep находит символ \r, выходы подзаголовка с ненулевым статусом; главный скрипт выходит и с этим кодом (из-за set -e).

Ответ на ваш вопрос Зачем нужны скобки?: потому что вы, вероятно, хотите выйти из основного сценария, если grep находит символ \r в одном из файлов под контролем git.

Смежные вопросы