Навеяно этим вопросом:
Что должен делать оператор 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
воспринимает это как true или false в зависимости от статуса команды, а не от ее вывода.
Вот сценарий, демонстрирующий такое поведение:
#!/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", чтобы объяснить это.
(Или, возможно, я упускаю что-то очевидное.)
EDIT : В свете принятого ответа, вот еще один пример такого поведения:
command='' ; if $command ; then echo yes ; else echo no ; fi
или, эквивалентно:
command= ; if $command ; then echo yes ; else echo no ; fi