2017-01-12 8 views
0

Я предполагаю mytrue и myfalse считаются строками вместо команд:Bash: как оценить результаты команд в двойных скобках

myfalse() { 
    return 0 
} 

mytrue() { 
    return 1 
} 

test-conditional () { 
    SHOW="dont-show" 
    [[ ${SHOW} == "show" || mytrue ]] && echo "ok" || echo "wrong" 
    [[ ${SHOW} == "show" && mytrue ]] && echo "err" || echo "ok" 
    [[ ${SHOW} == "show" || myfalse ]] && echo "err" || echo "ok" 
    [[ ${SHOW} == "show" && myfalse ]] && echo "err" || echo "ok" 
    SHOW="show" 
    [[ ${SHOW} == "show" || mytrue ]] && echo "ok" || echo "err" 
    [[ ${SHOW} == "show" && mytrue ]] && echo "ok" || echo "err" 
    [[ ${SHOW} == "show" || myfalse ]] && echo "ok" || echo "err" 
    [[ ${SHOW} == "show" && mytrue ]] && echo "err" || echo "ok" 

} 

test-conditional 

Так что это показывает неправильный вывод:

ok 
ok 
err 
ok 
ok 
ok 
ok 
err 

(Это должно be ok)

Как оценить команды внутри двойных скобок?

+0

У вас нет, просто снимите скобки. или включать только '==' сравнение внутри, т. е. [[$ {SHOW} == "show"]] || mytrue' – 123

+0

Также 0 истинно в bash. – 123

ответ

4

У вас есть функции true и false, возвращающие обратные коды возврата, и ваше последнее условие требует коррекции.

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

myfalse() { 
    return 1 
} 

mytrue() { 
    return 0 
} 

test-conditional () { 
    SHOW="dont-show" 
    [[ ${SHOW} == "show" ]] || mytrue && echo "ok" || echo "wrong" 
    [[ ${SHOW} == "show" ]] && mytrue && echo "err" || echo "ok" 
    [[ ${SHOW} == "show" ]] || myfalse && echo "err" || echo "ok" 
    [[ ${SHOW} == "show" ]] && myfalse && echo "err" || echo "ok" 
    SHOW="show" 
    [[ ${SHOW} == "show" ]] || mytrue && echo "ok" || echo "err" 
    [[ ${SHOW} == "show" ]] && mytrue && echo "ok" || echo "err" 
    [[ ${SHOW} == "show" ]] || myfalse && echo "ok" || echo "err" 
    [[ ${SHOW} == "show" ]] && myfalse && echo "err" || echo "ok" 
} 

test-conditional 

Также обратите внимание, как вызов функции находится вне [[ ... ]] в противном случае он не будет вызывать функцию.

Эти правила применяются при оценке этих выражений:

  1. Состояние после && не вычисляется, если первое условие не выполняется.
  2. Состояние после || не оценивается, если первое условие выполнено успешно.
+0

Спасибо. Не могли бы вы объяснить, как оцениваются эти логические выражения? Каковы правила приоритета? Всегда называются mytrue/myfalse? Я предполагаю, что нет, потому что эхо не всегда называется. Как это точно работает? – dangonfast

+0

Это стандартные логические конструкции программирования. 1. Условие после '&&' не оценивается, если первое условие терпит неудачу. 2. Условие после '||' не оценивается, если первое условие выполнено успешно. – anubhava

+0

И '&&' имеет превенцию над '||'? Это: 'a && b || c' означает '(a && b) || c' и 'a || b && c' означает 'a || (b && c) '? Это сбивает с толку, потому что операторы && в bash, кажется, делают несколько разные вещи внутри и вне скобок (возможно, не в случае использования двойных скобок) – dangonfast

1

Внутри Баш [[…]] (и внутри старых […] в большинстве оболочек), что имеет значение, если значение испытания имеет несколько символов или нет:

$ [[ somevalue ]] && echo "yes" || echo "no" 

Если значение испытанные если пусто, то тест не пройден :

$ [[ "" ]] && echo "yes" || echo "no" 
no 

это также верно и для переменных:

$ somevalue="a false string" 
$ [[ $somevalue ]] && echo "yes" || echo "no" 
yes 

$ somevalue="" 
$ [[ $somevalue ]] && echo "yes" || echo "no" 
no 

Таким образом, [[…]] ограничивается тестированием строк, а не «кодами выхода».
Ваши функции определяют «коды выхода», а не строки.
Вы можете

  1. определяют значения mytrue и myfalse быть переменными, которые представляют эти значения:

    mytrue=A_True_Value 
    myfalse="" 
    

    И использовать их:

    $ show="dont-show" 
    $ [[ ${SHOW} == "show" || $mytrue ]] && echo "ok" || echo "wrong" 
    ok 
    
    $ [[ ${SHOW} == "show" || $myfalse ]] && echo "ok" || echo "wrong" 
    wrong 
    
  2. Или, на самом деле тест выход коды за пределами [[…]] идиома:

    $ mytrue(){ return 0; } 
    $ if mytrue; then echo "ok"; else echo "wrong"; fi 
    ok 
    
    $ mytrue && echo "ok" || echo "wrong" 
    ok 
    
  3. Один (более сложный) альтернатива, чтобы сделать функции испускают значение и вызвать выполнение кода в функции от [[…]] идиомы:

    $ mytrue(){ echo "A_True_Value"; } 
    $ myfalse(){ echo ""; } 
    $ show="dont-show" 
    $ [[ ${SHOW} == "show" || $(mytrue) ]] && echo "ok" || echo "wrong" 
    ok 
    

ПОЦЕЛУЯ

Но (возможно) наиболее простым решением является наилучшее решение:

myfalse="" 
mytrue="true" 

test-conditional() { 
    show="dont-show" 
    [[ ${show} == "show" || $mytrue ]] && echo "ok" || echo "wrong" 
    [[ ${show} == "show" && $mytrue ]] && echo "err" || echo "ok" 
    [[ ${show} == "show" || $myfalse ]] && echo "err" || echo "ok" 
    [[ ${show} == "show" && $myfalse ]] && echo "err" || echo "ok" 
    show="show" 
    [[ ${show} == "show" || $mytrue ]] && echo "ok" || echo "err" 
    [[ ${show} == "show" && $mytrue ]] && echo "ok" || echo "err" 
    [[ ${show} == "show" || $myfalse ]] && echo "ok" || echo "err" 
    [[ ${show} == "show" && $myfalse ]] && echo "err" || echo "ok" 
} 

test-conditional 
+0

Фактически, mytrue и myfalse не являются константами: я использую это для моделирования функции' check', которая может возвращать 1 для false и 0 для true (я использовал неправильные возвращаемые значения в моем исходном вопросе). Тем не менее, мне нравится простота последнего раздела в вашем ответе: как я могу это сделать, убедившись, что: 1) функция 'check' называется 2) проверяется возвращаемое значение, а не испущенный текст – dangonfast

+0

Внутри [ [...]] вы можете только проверить текст (переменную) или вывод команды (function/alias). Если вы установите требование 'не выпущенной части текста', то вы отклоняете« вывод команды », тогда единственный способ сделать тест - использовать переменную. Это решение, которое я написал. (Contd ....) – sorontar

+0

Единственной альтернативой является проведение тестов за пределами [[...]]. Это то, что было предоставлено другими пользователями, создав составную команду «AND-OR». Я не могу понять, как выполнить код и проверить значение (это не «испущенный текст»), даже с арифметическими расширениями. Мне кажется, что все ваши требования могут быть выполнены одновременно. (Продолжение) – sorontar