2010-07-06 7 views
3

Каков порядок выражения выражений test или [ в скрипте bash? Это то же самое, что и порядок, в котором они написаны? Все они оцениваются?Что такое оценочный заказ команды «тест»?

В следующем примере:

if [ expr1 -a -n expr2 ] 

будет выражение2 быть оценены, если выражение1 является ложным?

+0

Пример не анализируется в bash. -a проверяет существование файла, -n проверяет ненулевое значение строки. Пример приводит к ошибке «слишком много аргументов». – BjoernD

+0

Я ничего не нашел о порядке оценки в manpages 'bash' или' test', поэтому он, похоже, зависит от реализации. Поскольку выражения 'test' никогда не изменяют состояние или не создают исключение, порядок оценки и лень не имеют значения. – Philipp

+1

@Bjoern, он разбирает штраф. Я не уверен, что вы используете, но работает под CygWin. Это более старый стиль теста, использующий '-a', чтобы делать" и ". – paxdiablo

ответ

11

Прошло много времени с тех пор, как я использовал этот особый синтаксис. В настоящее время, я предпочитаю:

if [[ expr1 && -n expr2 ]] 

, так как я знаю, , что это короткое замыкание. Страница bash людей в частности, гласит:

В && и || операторов не оценивает expression2, если значение expression1 достаточно для определения возвращаемого значения всего условного выражения.

Это не кажется, четко в одну сторону или другую сторону для варианта [ и test (с использованием -a).

Однако, в интересах содействия вашим знаниям и моим (и указание на то, почему с открытым исходным кодом является хорошей вещью), я пошел троллинг через исходный код bash.

Оказалось, что это не короткое замыкание в этом случае. Конкретные куски кода (сжатый немного для удобства чтения):

static int or() { 
    int value, v2; 
    value = and(); 
    if (pos < argc && argv[pos][0] == '-' 
     && argv[pos][1] == 'o' && !argv[pos][2]) 
    { 
     advance (0); 
     v2 = or(); 
     return (value || v2); 
    } 
    return (value); 
} 

static int and() { 
    int value, v2; 
    value = term(); 
    if (pos < argc && argv[pos][0] == '-' 
     && argv[pos][1] == 'a' && !argv[pos][2]) 
    { 
     advance (0); 
     v2 = and(); 
     return (value && v2); 
    } 
    return (value); 
} 

Вы можете видеть, в обоих случаях, что она продолжает интерпретировать выражения независимо от состояния первого выражения.

Это было от bash 2.5, но я только что проверил источник 4.1, и он не изменился. Источник был вытащен прямо из horse's mouth.

So. нижняя строка: представляется, что все подвыражения оцениваются при использовании -a и -o с test или [.

+1

Holy ... bash! Ты в порядке :) – Tom

Смежные вопросы