bash if оператор поведение вопрос

bash if оператор поведение вопрос

Я написал следующий фрагмент bash-скрипта.

if [ $(tmux has -t junk) ]
then
echo zero
else
echo one
fi

Он всегда возвращает единицу, независимо от того, существует сеанс или нет. Я проверил в командной строке, выполнив оператор tmux, а затем запустив $? . Он ведет себя так, как и ожидалось, ноль, если сеанс существует, и один, если сеанса не существует. Почему оператор if не ведет себя так же? Я попробовал изменить оператор if, как показано ниже

tmux has -t junk
if [ $? -eq 0 ]
then
echo zero
else
echo one
fi

Вышеуказанная штука работает. Так что не так с первым блоком операторов?

решение1

Как уже упоминалось, if [ $(tmux has -t junk) ]расширьте до значения, if [ ]которое оценивается как ложное.

Вы можете использовать:

if tmux has -t junk; then
    echo OK
else
    echo ERR
fi

Или, если хотите короче:

tmux has -t junk || echo ERR

Или

tmux has -t junk && echo OK || echo ERR

Вы также можете его отрицать, если это более уместно, например:

! tmux has -t junk || echo OK
! tmux has -t junk && echo ERR || echo OK
etc.

Редактировать:

Также не стоит забывать, что если команда создает вывод, вы можете захотеть перенаправить этот вывод в черную дыру, например /dev/null:

 if my_cmd >/dev/null; then echo OK else; echo ERR; fi

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

 if my_cmd >/dev/null 2>&1; then echo OK else; echo ERR; fi

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

Как уже упоминалось: $?это единственный способ получить возвращаемое программой значение.

Некоторые программы различаются по возврату и могут иметь довольно явное значение.

Так, например:

mycmd
ecode=$?

case "$ecode" in
0) echo "Success";;
1) echo "Operation not permitted";;
2) echo "No such file or directory";;
esac

Благодаря этому можно предпринять соответствующие действия в случае конкретных ошибок.

Если у вас установлен MySQL, вы можете сделать это, например, так:ужас:

for i in {0..50}; do perror $i; done
# And
for i in {1000..1050}; do perror $i; done

чтобы почувствовать это.

Смотрите такжеэтот ответсвязанные с ошибками, специфичными для ОС, которые также ссылаются на документ Open GroupsНомера ошибокиerrno.h.

Или взгляните наSQLiteИ егорасширенные.

решение2

Когда вы используете:

if [ $(tmux has -t junk) ]

При этом проверяется вывод команды, tmux has -t junkно не возвращаемое значение.

Так как он всегда печатает единицу, как в первом случае, это означает, что tmux has -t junkкоманда ничего не печатает на стандартном выводе.

Итак, в первом случае,

if [ $(tmux has -t junk) ] 

оценивается как

if [ ]

Связанный контент