Gdzie są kontynuacje linii bash po && i || udokumentowane?

28

Często widziałem ten konstrukt w skryptach i sam go używałem, ale niepokoi mnie to, że nie mogę go znaleźć w dokumentacji.

Przykład:

[ -f file1 ] &&
[ -f file2 ] &&
echo "Both files exist." ||
echo "One or the other file doesn't exist."

Można to również zrobić za pomocą ukośników odwrotnych przed znakami nowej linii, jak wspomniano w man bash:

If a \<newline> pair appears,  and  the  backslash  is  not
itself  quoted,  the \<newline> is treated as a line continuation (that
is, it is removed from the input stream and effectively ignored).

Przykład:

[ -f file1 ] && \
[ -f file2 ] && \
echo "Both files exist." || \
echo "One or the other file doesn't exist."

... ale to nie wydaje się konieczne. Pierwsza wersja powyżej działa nawet bez ukośników.

Gdzie mogę to znaleźć man bash? (Czy ta bashspecyfikacja jest zgodna z POSIX?)

Dzika karta
źródło
Jeśli szukasz oficjalnej dokumentacji bash lub POSIX, zobacz odpowiedź Gillesa. Ale zostało to omówione w rozdziale Jakie są operatory kontroli i przekierowania powłoki? - Inne obserwacje ;, &, (i) .
G-Man mówi „Reinstate Monica”
@ G-Man, myślę, że to nie było skierowane na mnie? Tylko dla przyszłych czytelników? Jak powiedziałem w pytaniu: „niepokoi mnie to, że nie mogę tego znaleźć w dokumentacji”. Wiedziałem już, jak to działa, więc w rzeczywistości była to tylko prośba o oficjalną dokumentację. :)
Wildcard,
Nawet w przypadku tablic, jest niejawna linii kontynuacją: names=( Rama Soma<newline> Sita Diya ). Python wyraźnie je tutaj opisuje , ale wydaje się, że dokumentacja Bash nie.
jamadagni

Odpowiedzi:

39

Znak nowej linii jest ignorowany w kilku kontekstach, w których występuje oczywiście niezakończone polecenie. Konteksty te obejmują po operatora sterującego ( &&, ||, |, &, ;, ;;, ale nie !).

Nie widzę tego udokumentowanego w podręczniku bash.

W POSIX jest określony przez reguły gramatyczne . Gdziekolwiek reguły mają linebreak, możesz mieć zero lub więcej podziałów linii.

Gilles „SO- przestań być zły”
źródło
+1, nie wiedziałem, że to działa dla prostej rury (|). Chciałbym, abyśmy umieścili je również w następnym wierszu, dla czytelności, ale to nie działa w ten sposób (jeśli to zrobisz, musisz wprowadzić poprzedni nowy wiersz).
Olivier Dulac
1
@OlivierDulac Jak to może działać? Kiedy przetwarza bieżący wiersz poleceń, skąd ma wiedzieć, że planujesz pisać |na początku następnego wiersza? Pamiętaj, że powłoka jest również używana interaktywnie, nie tylko w skryptach, a gramatyka jest taka sama.
Barmar
@Barmar: Wiem, wiem o tym (napisałem kompilatory w szkole ^^) ... Powiedziałem „życzę” i nie jest to bardzo prawdopodobne życzenie
Olivier Dulac
1
@DocSalvager, czy możesz podać przykład błędu logicznego, który mógłby pomóc? Trudno mi to zobaczyć ...
Wildcard,
2
@DocSalvager, tak naprawdę nie używałbym kodu tak, jak go napisałem - była to ilustracja. Jednak bez ostatniego wiersza (klauzula else) użyłbym tego w ten sposób. (Bo „jeśli to i to, to zrób to” this && this2 && thatjest w porządku, ale dla elseklauzuli użyłbym faktycznego if then else fi.)
Wildcard