Вдохновлен этим вопросом :
Что должен делать оператор 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
обрабатывает его как истинное или ложное в зависимости от состояния команды, а не от ее вывода.
Вот скрипт, который демонстрирует поведение:
#!/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 "Shell Command Language", чтобы объяснить это.
(Или, может быть, я упускаю что-то очевидное.)
РЕДАКТИРОВАТЬ: В свете принятого ответа, вот еще один пример поведения:
command='' ; if $command ; then echo yes ; else echo no ; fi
или, что эквивалентно:
command= ; if $command ; then echo yes ; else echo no ; fi