Как я могу сделать что-то подобное в Bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Как я могу сделать что-то подобное в Bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Ответы:
Как сделать что-то условно, если команда выполнена успешно или не выполнена
Это именно то, что if
делает заявление Bash :
if command ; then
echo "Command succeeded"
else
echo "Command failed"
fi
Добавление информации из комментариев: вам не нужно использовать синтаксис [
... ]
в этом случае. [
сама по себе команда, почти эквивалентна test
. Это, вероятно, самая распространенная команда для использования в an if
, что может привести к предположению, что она является частью синтаксиса оболочки. Но если вы хотите проверить, была ли команда выполнена успешно, используйте непосредственно саму команду if
, как показано выше.
Изменить: процитировал вопрос в верхней части для ясности (этот ответ не появляется в верхней части страницы).
then
на отдельной строке.
if ! command ; then ... ; fi
. [
сама по себе команда, и в этом случае она не нужна.
if [ ! command ]
не выполняется command
; он обрабатывается command
как строка и обрабатывается как истина, потому что он имеет ненулевую длину. [
это синоним test
команды
Для небольших вещей, которые вы хотите случиться, если работает команда оболочки, вы можете использовать &&
конструкцию:
rm -rf somedir && trace_output "Removed the directory"
Точно так же для небольших вещей, которые вы хотите, чтобы произошла ошибка команды оболочки, вы можете использовать ||
:
rm -rf somedir || exit_on_error "Failed to remove the directory"
Или оба
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
Вероятно, неразумно делать очень много с этими конструкциями, но иногда они могут сделать процесс контроля намного понятнее.
Проверьте значение $?
, которое содержит результат выполнения самой последней команды / функции:
#!/bin/bash
echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
echo success
else
echo failed
fi
if [ $RESULT == 0 ]; then
echo success 2
else
echo failed 2
fi
if
идиому Баша . Я предпочитаю ответ Кита Томпсона.
if
состоит в том, чтобы сделать это. Условия контроля потока в Баше все исследуют $?
за кулисами; это то, что они делают. Явное изучение его значения должно быть ненужным в подавляющем большинстве случаев и, как правило, является антипаттерном для начинающих.
if ! cmd
это нормально. В противном случае, общая договоренность заключается в использовании else
пункта. У вас не может быть пустого, then
но вы иногда видите, then : nothing; else
где :
неактивность важна. true
будет работать там же.
Это сработало для меня:
command && echo "OK" || echo "NOK"
если command
успешно, то echo "OK"
выполняется, и так как это успешно, выполнение останавливается там. В противном случае &&
пропускается и echo "NOK"
выполняется.
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))
?
echo "OK"
часть может сама выйти из строя, то это лучше:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
Следует отметить, что if...then...fi
и &&
/ ||
тип подхода имеет дело с состоянием выхода, возвращаемым командой, которую мы хотим проверить (0 в случае успеха); однако некоторые команды не возвращают ненулевой статус выхода, если команда не выполнена или не может обработать ввод. Это означает, что обычный if
и &&
/ ||
подходы не будут работать для этих конкретных команд.
Например, в Linux GNU по- file
прежнему завершает работу с 0, если он получил несуществующий файл в качестве аргумента и find
не может найти указанный файл пользователем.
$ find . -name "not_existing_file"
$ echo $?
0
$ file ./not_existing_file
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0
В таких случаях одним из возможных способов справиться с ситуацией является чтение stderr
/ stdin
сообщения, например, те, которые были возвращены file
командой, или анализ выходных данных команды, как в find
. Для этого case
можно использовать заявление.
$ file ./doesntexist | while IFS= read -r output; do
> case "$output" in
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed
$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi
File not found
Наиболее подверженной ошибкам я могла придумать:
RR=$?
Теперь, не только для этой ситуации, но и для других, с которыми вы можете столкнуться, подумайте:
$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi
Ответ: да
$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi
Ответ: нет
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
Ответ: нет
$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi
Ответ: да
$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi
Ответ: да
Это предотвращает все виды ошибок.
Вы, наверное, знаете весь синтаксис, но вот несколько советов:
"blank"
быть nothing
.${variable}
.base-8
. Вы получите ошибку вроде:
value too great for base (error token is "08")
для чисел выше 7
. Вот когда 10#
вступает в игру:10#
заставляет число быть base-10
.Ты можешь сделать это:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
echo "ping response succsess!!!"
fi
ping
которой записывается с учетом запуска его в виде команды. Но поскольку выходные данные перенаправляются в / dev / null, это всегда будет пустой строкой. Таким образом, вы ничего не запускаете в подоболочке, что означает, что предыдущее состояние выхода (подзаголовок подстановки команд, то есть ping) будет сохранено. Очевидно, правильный путь if ping ...; then
здесь.
Как отмечено в другом месте в этой теме, исходный вопрос в основном отвечает сам. Вот иллюстрация, показывающая, что if
условия также могут быть вложенными.
В этом примере if
проверяется, существует ли файл и является ли он обычным файлом. Если эти условия выполняются, проверьте, имеет ли он размер больше 0.
#!/bin/bash
echo "Which error log are you checking today? "
read answer
if [ -f /opt/logs/$answer*.errors ]
then
if [ -s /opt/logs/$answer*.errors ]
then
echo "Content is present in the $answer error log file."
else
echo "No errors are present in the $answer error log file."
fi
else
echo "$answer does not have an error log at this time."
fi
#!/bin/bash
if command-1 ; then
echo "command-1 succeeded and now running from this block command-2"
command-2
else
echo "command-1 failed and now running from this block command-3"
command-3
fi
Это может быть сделано просто так, так как $?
дает вам статус последней выполненной команды.
Так может быть
#!/bin/sh
... some command ...
if [ $? == 0 ] ; then
echo '<the output message you want to display>'
else
echo '<failure message>'
fi