Вдохновленный этот вопрос:
Что должен делать оператор if, когда условие является заменой команды, когда команда не производит вывод?
ПРИМЕЧАНИЕ: Пример if $(true); then ...
, а не if true ; then ...
Например, данный:
if $(true) ; then echo yes ; else echo no ; fi
Я бы подумал, что $(true)
следует заменить выходом команды true
, которая ничего. Затем он должен быть эквивалентен этому:
if "" ; then echo yes ; else echo no ; fi
который печатает no
, потому что нет команды, имя которой является пустой строкой, или к этому:
if ; then echo yes ; else echo no ; fi
который является синтаксической ошибкой.
Но эксперимент показывает, что если команда не производит вывод, оператор if
рассматривает его как истинный или ложный в зависимости от состояния команды, а не от ее выхода.
Здесь script, который демонстрирует поведение:
#!/bin/bash
echo -n 'true: ' ; if true ; then echo yes ; else echo no ; fi
echo -n 'false: ' ; if false ; then echo yes ; else echo no ; fi
echo -n '$(echo true): ' ; if $(echo true) ; then echo yes ; else echo no ; fi
echo -n '$(echo false): ' ; if $(echo false) ; then echo yes ; else echo no ; fi
echo -n '$(true): ' ; if $(true) ; then echo yes ; else echo no ; fi
echo -n '$(false): ' ; if $(false) ; then echo yes ; else echo no ; fi
echo -n '"": ' ; if "" ; then echo yes ; else echo no ; fi
echo -n '(nothing): ' ; if ; then echo yes ; else echo no ; fi
и здесь вывод я получаю (Ubuntu 11.04, bash 4.2.8):
true: yes
false: no
$(echo true): yes
$(echo false): no
$(true): yes
$(false): no
"": ./foo.bash: line 9: : command not found
no
./foo.bash: line 10: syntax error near unexpected token `;'
./foo.bash: line 10: `echo -n '(nothing): ' ; if ; then echo yes ; else echo no ; fi'
Первые четыре строки ведут себя так, как я ожидал; строки $(true)
и $(false)
удивительны.
Дальнейший эксперимент (не показан здесь) указывает, что если команда между $(
и )
выдает вывод, его статус выхода не влияет на поведение if
.
Я вижу подобное поведение (в некоторых случаях - разные сообщения об ошибках) с bash
, ksh
, zsh
, ash
и dash
.
Я ничего не вижу в документации bash или в спецификации языка командной строки POSIX, чтобы объяснить это.
(Или, возможно, мне не хватает чего-то очевидного.)
EDIT: В свете принятого ответа, вот еще один пример поведения:
command='' ; if $command ; then echo yes ; else echo no ; fi
или, что эквивалентно:
command= ; if $command ; then echo yes ; else echo no ; fi