Что -e делает в Bash Shebang?

32

У меня есть скрипт bash со следующим:

#!/bin/bash -e

egrep "^username" /etc/passwd >/dev/null 
if[ $? -eq 0 ] 
then 
  echo "doesn't exist" 
fi

Этот скрипт не будет работать без -e. Что делает -eдля этого сценария? Кроме того, что делает $?в этом контексте?

Крис Генри
источник
1
Странный. Нет -eна странице руководства (я действительно хочу увидеть ответ на этот адрес). $?содержит последний код выхода (код egrepпроцесса , созданного выше).
2
@pst: -eзадокументировано под set.
Грег Хьюгилл
Вы могли бы упростить свой сценарий, выполнив это:if egrep -q "^username" /etc/passwd ; then echo "doesn't exist" ; fi
bollovan
2
Вам не хватает пробела между ifи [. Этот сценарий не будет работать с -e , потому что , если grepничего не находит , то под -eсценарий будет прекратить прямо там. Без -e, вы получите сообщение в обратном направлении: статус ( $?) 0 означает, что grep действительно нашел пользователя. Обратите внимание, что это должно быть `grep '^ username:', кстати (что, если есть другой пользователь с более длинным именем?).
Жиль "ТАК - перестань быть злым"
3
Будет ли #/bin/bash -eиметь тот же эффект, что и #/bin/bashв строке № 1 и set -eв строке № 2?
Блонг

Ответы:

34

Ошибка выхода. Больше флагов

Если есть ошибка, она сразу выйдет.

$? это выход из предыдущей команды. В Linux состояние выхода 0 означает, что команда была успешной. Любой другой статус будет означать, что произошла ошибка.

egrep "^ username" / etc / passwd> / dev / null Будет искать имя пользователя в файле / etc / passwd. Если он найдет его, то будет завершен статус $? будет равно 0. Если он не найдет его, статус выхода будет чем-то другим (не 0), следовательно, вы будете "эхо не существует".


источник
Кроме того, вы можете заставить скрипт работать правильно без -e, заменив первые две строки на if egrep "^username" /etc/passwd >/dev/null.
1
Почему не setтребуется, хотя? : - /
1
@pst: потому что -eдля bash задан аргумент командной строки. Все опции, перечисленные ниже set, также принимаются bash в командной строке - обратите внимание на первое предложение в разделе Опции страницы руководства.
Гравитация
14

Все ключи командной строки bash описаны в man bash.

      -e немедленно выйти, если конвейер (который может состоять из
              одна простая команда), команда subshell, заключенная в
              скобки или одна из команд, выполняемых как часть
              список команд, заключенный в фигурные скобки (см. ОБРАЗЕЦ ОБОЛОЧКИ
              выше) выходы с ненулевым статусом. Оболочка не
              выход, если команда, которая терпит неудачу, является частью команды
              список сразу после или до ключевого слова,
              часть теста после if или elif зарезервирована
              слова, часть любой команды, выполненной в && или || список
              кроме команды, следующей после финальной && или ||, любой
              команда в конвейере, но последняя, ​​или если команда
              возвращаемое значение инвертируется с! Ловушка на ERR,
              если установлено, выполняется до выхода из оболочки. Этот вариант
              применяется к среде оболочки и каждая подоболочка окружения
              отдельно (см. КОМАНДА ИСПОЛНИТЕЛЬНОЙ СРЕДЫ
              выше), и может привести к выходу подоболочек перед выполнением
              все команды в подоболочке.
Грег Хьюгилл
источник
2
Ааа. Я искал это в человеке, но после нахождения -e в файле тестов и отсутствия -e по основным аргументам я сдался. Хороший отрывок. Почему не setтребуется, хотя? : - /
1

Ваш скрипт неверен, потому что

egrep "^username" /etc/passwd >/dev/null 
if[ $? -eq 0 ] 
then 
  #echo "doesn't exist" # WRONG
  echo "the USER EXISTS"
fi

статус выхода 0 - значит - все ок, в случае с grep значит "ОК, найдена строка". состояние выхода! = 0 означает, что что-то не так, в случае с grep 1 означает «не найден», 2 означает «невозможно открыть ввод» ...

jm666
источник