7

Bash игнорирует ошибку для конкретной команды

35

Я использую следующие опции в bash-скрипте:

set -o pipefail
set -e

Это позволяет остановить выполнение скрипта при возникновении ошибки. У меня есть скрипт примерно на 100 строк, и я не хочу проверять код возврата каждой строки.

Однако для одной конкретной команды я хочу игнорировать ошибку. Как мне это сделать?

5 ответ(ов)

12

Решение:

particular_script || true

Пример:

$ cat /tmp/1.sh
particular_script()
{
    false
}

set -e

echo один
particular_script || true
echo два
particular_script
echo три

$ bash /tmp/1.sh
один
два

три никогда не будет напечатано.

Также стоит отметить, что когда опция pipefail активирована, оболочке достаточно, чтобы она считала, что весь пайп имеет ненулевой код возврата, если одна из команд в пайпе завершилась с ненулевым кодом (при выключенном pipefail это должно быть последней командой).

$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0
2

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

set -e
EXIT_CODE=0
command || EXIT_CODE=$?
echo $EXIT_CODE

В этом коде set -e позволяет остановить выполнение скрипта при возникновении ошибки, но мы обходим этот механизм. Переменная EXIT_CODE инициализируется значением 0, и если команда command завершится неуспешно, код ошибки сохраняется в переменной EXIT_CODE. В конце скрипта вы можете вывести значение переменной EXIT_CODE, чтобы узнать, завершилась ли команда успешно или с ошибкой.

2

Просто добавьте || true после команды, выполнение которой вы хотите игнорировать ошибки.

0

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

set +e
find "./csharp/Platform.$REPOSITORY_NAME/obj" -type f -iname "*.cs" -delete
find "./csharp/Platform.$REPOSITORY_NAME.Tests/obj" -type f -iname "*.cs" -delete
set -e

Вы можете отключить прерывание скрипта при ошибках с помощью set +e. Это позволит игнорировать все ошибки после этой строки. Когда вы закончите с этими командами и захотите, чтобы скрипт снова прерывался при возникновении ошибок, используйте set -e.

После применения set +e команда find больше не приведет к сбою всего скрипта, даже если файлы не найдены. В то же время, сообщения об ошибках от find все еще будут отображаться, но весь скрипт продолжит выполняться. Это облегчает отладку, если это вызывает проблемы.

Это может быть полезно для CI и CD, например, в GitHub Actions.

0

Спасибо за простое решение, представленное выше:

<particular_script/command> || true

Следующую конструкцию можно использовать для выполнения дополнительных действий, диагностики шагов скрипта и для управления потоком выполнения:

if <particular_script/command>
then
   echo "<particular_script/command> выполнен успешно!"
else
   echo "<particular_script/command> завершился неудачно!"
   #exit 1
fi

Мы можем прервать дальнейшие действия и вызвать exit 1, если это необходимо.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь