Вопрос или проблема
Это:
$ echo $VAR
что-то
И это:
$ [[ -z "$VAR" ]]
$ echo $?
1
Но это:
if [[ -z "$TMUX_MAN_PANE" ]]; then
echo 'НИКОГДА НЕ ПЕЧАТАЕТ!'
Это меня сбивает с толку.
ОБНОВЛЕНИЕ
Вот немного настоящего кода. Я не могу заставить это работать.
tmux_man_page() {
if [[ "$TERM" =~ 'screen' ]] && [[ -n "$TMUX" ]]; then
tmux list-panes -t $TMUX_MAN_PANE &> /dev/null
echo $?
echo $TMUX_MAN_PANE
[[ -z "$TMUX_MAN_PANE" ]]
echo $?
if ! [[ -z "$TMUX_MAN_PANE" ]] && [[ $? ]]; then
echo debug1
tmux -q respawn-pane -k -t $TMUX_MAN_PANE man $1
else
echo debug2
tmux split-window -vf man $1
TMUX_MAN_PANE=$(tmux display-message -p "#{pane_id}")
export TMUX_MAN_PANE
tmux select-pane -t {last}
fi
fi
}
ОБНОВЛЕНИЕ 2: Успех
Наконец-то разобрался. Были проблемы с получением статуса первой строки в операторе if. Пришлось прибегнуть к хитрости, чтобы получить вывод оператора tmux в первой строке оператора if. Если кто-то знает более чистый способ сделать это, я весь во внимании.
Вот рабочий код:
tmux_man_page() {
if [[ "$TERM" =~ 'screen' ]] && [[ -n "$TMUX" ]]; then
pane=$(tmux list-panes -t $TMUX_MAN_PANE 2>&1)
if ! [[ -z "$TMUX_MAN_PANE" ]] && ! [[ $pane =~ 'find pane' ]]; then
tmux -q respawn-pane -k -t $TMUX_MAN_PANE man $1
else
tmux split-window -vf man $1
TMUX_MAN_PANE=$(tmux display-message -p "#{pane_id}")
export TMUX_MAN_PANE
tmux select-pane -t {last}
fi
fi
}
tmux_man_page_close() {
if [ $TMUX_MAN_PANE ]; then
tmux kill-pane -t $TMUX_MAN_PANE
fi
}
Ключ в том, что код возврата 0
означает истину/успех, а 1
(или любое другое ненулевое значение) означает ложь/неудачу.
В оболочке проверка, которая является истиной (т.е. программа, которая успешно завершилась), возвращает код 0. Проверка [[ -z "$VAR" ]]
возвращает код ноль (истина), если $VAR
пусто, или один (ложь), если оно не пусто:
$ var=""; [[ -z "$var" ]]; echo $?
0
$ var="НЕ ПУСТО"; [[ -z "$var" ]]; echo $?
1
В итоге, если $VAR
не пусто, то [[ -z "$VAR" ]]
ложно (возвращает 1
), и оператор then
не выполняется.
Вы хотели, чтобы проверка возвращала истину, если переменная не пустая? Если да, замените -z
на -n
:
$ var=""; [[ -n "$var" ]]; echo $?
1
$ var="НЕ ПУСТО"; [[ -n "$var" ]]; echo $?
0
Для краткости та же проверка выполняется, если -n
опущен:
$ var=""; [[ "$var" ]]; echo $?
1
$ var="НЕ ПУСТО"; [[ "$var" ]]; echo $?
0
(Обратите внимание, что в арифметическом контексте истинностные значения такие же, как и в большинстве языков программирования, где ноль рассматривается как ложь. Так, например, if (( a )); then echo "$a is non-zero"; fi
. Но арифметические проверки также соблюдают эту конвенцию, так что вы получаете правильное поведение с (( a != 0 ))
тоже.)
Ответ или решение
Вопрос о том, как Bash интерпретирует истинные и ложные значения в контексте проверки условий, может сбить с толку многих пользователей. Давайте разберем это подробнее.
Bash использует концепцию кодов выхода, чтобы определить, является ли выражение истинным или ложным. В соответствии с этой концепцией:
- Код выхода 0: означает, что выражение успешно и истинно.
- Код выхода 1 или любая другая не-нулевая величина: означает, что выражение ложно или завершилось с ошибкой.
Теперь к вашему примеру:
Когда вы используете команду [[ -z "$VAR" ]]
, Bash проверяет, пустая ли переменная VAR
. Опция -z
означает "zero-length" или "нулевая длина", и она возвращает истину (0), если переменная пустая. Следовательно, если VAR
содержит какое-либо значение, выражение [[ -z "$VAR" ]]
будет возвращать ложь (1).
Пример иллюстрирует это легко:
var=""; [[ -z "$var" ]]; echo $?
# Вывод: 0, поскольку var пустая
var="NOT EMPTY"; [[ -z "$var" ]]; echo $?
# Вывод: 1, поскольку var не пустая
Если ваша цель в том, чтобы проверить, является ли переменная НЕ пустой, следует использовать обратный оператор -n
, который возвращает истину (0), если переменная имеет значение:
var=""; [[ -n "$var" ]]; echo $?
# Вывод: 1, поскольку var пустая
var="NOT EMPTY"; [[ -n "$var" ]]; echo $?
# Вывод: 0, поскольку var не пустая
Следует отметить, что если вы просто используете [[ "$var" ]]
, это равнозначно проверке [[ -n "$var" ]]
и будет возвращать истину (0), если переменная не пустая, и ложь (1), если пустая.
В вашем случае, когда вначале была путаница с проверкой на [[ -z "$TMUX_MAN_PANE" ]]
, код работал так, что выражение возвращает ложь, если TMUX_MAN_PANE
непустая, и условный блок then
не выполняется.
Таким образом, понимание того, как Bash обрабатывает истинность и ложность через коды выхода, является ключевым при написании скриптов. Это позволяет избежать ошибок в логике программ, обеспечивая, что вы понимаете, когда ваши условия дейcтвительно выполняются.
Поскольку вопрос был связан с примерами из контекста скриптов в Bash, вы всегда должны убедиться, что правильно используете операторы, соответствующие вашей логике программы, и что выбранные операторы отражают ваше намерение достижения функциональности.
Оптимизация SEO: Включение ключевых слов, таких как Bash, проверка условий в Bash, операторы проверки переменных в Bash, добавят ценность для людей, ищущих информацию об этой теме.