Bash: условно на основе спецификаций c код выхода команды - PullRequest
0 голосов
/ 27 мая 2020

Этот вопрос является продолжением Bash условного условия на основе кода выхода команды .

Я понимаю и использовал принятый ответ на этот вопрос:

$ cat ./txt
foo
bar
baz
$ if ! grep -Fx bax txt &>/dev/null; then echo "not found"; fi
not found
$

Но я не могу понять синтаксис, чтобы осуществить, казалось бы, простой поворот к предпосылке: как я могу написать условное выражение для определенного c кода выхода команды?

В этом сообщении указано, что grep может завершиться ошибкой с кодом> 1; поэтому я хотел написать указанное выше условие для вывода «не найдено», если grep вернул код ошибки 1. Как я могу написать такое выражение? Следующее, похоже, не работает (я, очевидно, борюсь):

$ # Sanity-check that grep really fails with error code 1:
$ grep -Fx bax txt &>/dev/null
$ echo $?
1
$
$
$ if grep -Fx bax txt &>/dev/null -eq 1; then echo "not found"; fi
$ if grep -Fx bax txt &>/dev/null == 1; then echo "not found"; fi
$ if grep -Fx bax txt &>/dev/null = 1; then echo "not found"; fi
$ if [ grep -Fx bax txt &>/dev/null -eq 1 ]; then echo "not found"; fi
$ if [ grep -Fx bax txt &>/dev/null == 1 ]; then echo "not found"; fi
$ if [ grep -Fx bax txt &>/dev/null = 1 ]; then echo "not found"; fi
$

Примечание: я специально стараюсь не запускать сначала команду, а затем использовать $? в условном , по причинам, указанным в принятом ответе на первое отмеченное сообщение.

1 Ответ

1 голос
/ 27 мая 2020

Если вы хотите по-разному реагировать на разные коды ошибок (в отличие от просто успеха / неудачи, как в связанном вопросе), вам нужно запустить команду, а затем проверить $?, чтобы получить ее конкретный c статус выхода :

grep -Fx bax txt &>/dev/null
if [ $? -eq 1 ]; then
    echo "not found"
fi

(В моем ответе на связанный вопрос я описал тестирование, является ли $? нулем в качестве культового программирования автомобиля go; это не относится к проверке его на наличие c ненулевых значений .)

Обратите внимание, что $? переустанавливается для каждой выполняемой команды - включая ту, которая проверяет $? из предыдущей команды - поэтому, если вы хотите сделать с ней более одного действия, вы необходимо немедленно сохранить его в переменной, а затем запустить тесты для этой переменной:

curl "$url"
curl_status=$?
if [ "$curl_status" -eq 6 ]; then
    echo "Couldn't resolve host name"
elif [ "$curl_status" -eq 7 ]; then
    echo "Couldn't connect to host"
elif [ "$curl_status" -ne 0 ]; then
    echo "Some sort of error occurred; curl status was $curl_status"
fi

Обратите внимание, что использование ! для отрицания успеха / неудачи команды эффективно уничтожает указанные c код ошибки, потому что он преобразует все ненулевые коды в один и тот же результат: ноль. Если вы хотите выполнить эквивалент if ! command ... и по-прежнему иметь доступ к указанному коду c, моя любимая идиома - использовать || и группу скобок, например:

curl "$url" || {
    curl_status=$?
    ...
    # Do error handling/reporting based on $curl_status
    ...
}
...