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

В момента сме в директорията /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