Группировка команд (&&, ||, )

Сейчас мы находимся в каталоге /home/student/. Выполняем следующие команды:

pwd; (ls) || { cd .. && ls student/; }  && cd student || cd / && cd ;

Выполняются следующие команды: pwd, ls, cd student, cd /, cd

Вот что я думаю:

  • pwd выполняется, потому что это первая команда

  • (ls) выполняется в подоболочке, поскольку команды разделены
    символом ";"

  • код справа от || не выполняется, так как код слева
    от || был выполнен

Пока все ясно, я думаю. Но я понятия не имею, почему выполняются другие команды? Если кто-то может разбить его для меня, я был бы признателен.


person mythic    schedule 30.03.2015    source источник


Ответы (2)


Приоритет операторов для && и || строго слева направо.

Таким образом:

pwd; (ls) || { cd .. && ls student/; }  && cd student || cd / && cd ;

...эквивалентно...

pwd; { { { (ls) || { cd .. && ls student/; }; } && cd student; } || cd /; } && cd ; }

... разбивая это графически:

pwd; {                                      # 1
       {                                    # 2
         { (ls) ||                          # 3
                   { cd .. &&               # 4
                              ls student/;  # 5
                   };                       # 6
         } && cd student;                   # 7
       } || cd /;                           # 8
     } && cd ;                              # 9
  1. pwd происходит безоговорочно
  2. (только группировка)
  3. ls происходит (в подоболочке) безусловно.
  4. cd .. происходит, если (3) не удалось.
  5. ls student/ происходит, если (3) не удалось и (4) удалось
  6. (только группировка)
  7. cd student происходит, если либо (3) удалось, либо оба (4) и (5) удалось.
  8. cd / происходит, если [оба (3) и один из (4) или (5) не удались], или [(7) не удалась].
  9. cd происходит, если (7) произошло и успешно, или (8) произошло и успешно.

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

person Charles Duffy    schedule 30.03.2015

(ls) выполняется в подоболочке, так как команды разделены знаком ";"

ls выполняется в подоболочке из-за круглых скобок. Круглые скобки обозначают подоболочки.

Но я понятия не имею, почему выполняются другие команды?

В отличие от других языков программирования, с которыми вы, возможно, знакомы, bash не дает && более высокого приоритета, чем ||. Они имеют одинаковый приоритет и оцениваются слева направо.

Если бы у вас было a || b && c, на других языках это читалось бы как a || {b && c;}. Если бы a было истинным, то ни b, ни c не оценивались бы.

Однако в bash он анализируется как {a || b;} && c (строгий приоритет слева направо), поэтому, когда a истинно, b пропускается, но c все еще оценивается.

person John Kugelman    schedule 30.03.2015