2011-08-12 8 views
90

jestem zaznajomieni z tej składni:Składnia wielowierszowa dla orurowania heredoc; czy to jest przenośne?

cmd1 << EOF | cmd2 
text 
EOF 

ale właśnie odkrył, że bash pozwala mi napisać:

cmd1 << EOF | 
text 
EOF 
cmd2 

(heredoc służy jako wejście do cmd2). Wydaje się to bardzo dziwną składnią. Czy to jest przenośne?

+0

Przyszedłem tutaj, aby znaleźć dobry sposób na dzielenie się to na wielu liniach: 'big-Long-Command1 z dużą ilością args << EOF | big-long-command2 z dużą ilością argumentów. "Składnia nieparzysta" wydaje się być najlepszym sposobem. – PaulC

+0

Jednym z wygodnych przykładów użycia jest przekształcenie tabeli rozdzielanej spacjami w tabelę rozdzielaną tabulatorami, dzięki czemu można ją wkleić w Arkuszu kalkulacyjnym Google. Nie musisz tworzyć pliku tymczasowego. –

+0

Pierwszy nie działał dla mnie w powłoce z. Nie podoba mi się ten drugi, ponieważ alienuje | z polecenia, tracąc idiomaty (?) z powłokowych potoków. –

Odpowiedz

72

Tak, standard POSIX na to pozwala. According to the 2008 version:

tu-dokument powinien być traktowany jako jedno słowo, które rozpoczyna się po następny <newline> i trwa dopóki istnieje linia zawierająca tylko separator i <newline>, bez <blank> znaków pomiędzy nimi. Następnie rozpoczyna się następny dokument tutaj, jeśli taki istnieje.

i obejmuje ten przykład wielokrotności „tu-dokumentów” w tej samej linii:

cat <<eof1; cat <<eof2 
Hi, 
eof1 
Helene. 
eof2 

więc nie ma problemu robi przekierowania lub rury. Twój przykład jest podobny do mniej więcej tak:

cat file | 
cmd 

a gramatyki powłoki (dalej w dół na powiązanej stronie) zawiera te definicje:

pipe_sequence :        command 
       | pipe_sequence '|' linebreak command 

newline_list  :    NEWLINE 
       | newline_list NEWLINE 
       ; 
linebreak  : newline_list 
       | /* empty */ 

więc symbolem rura może być obserwowani przez końcowych of-line i nadal będą traktowane jako część rurociągu.

9

Hmm, pewnie tak, zgodnie z testem w bash w trybie POSIX:

$ bash --posix 
$ cat <<EOF | 
> ahoj 
> nazdar 
> EOF 
> sed 's/a/b/' 
bhoj 
nbzdar 
+1

działa również w 'desce' –

+0

Jeszcze jedna mała uwaga: nie umieszczaj spacji po zamknięciu 'EOF'. Monit będzie dziwnie się zachowywał, a będziesz się zastanawiał, co to jest, do cholery, nie tak –

+0

Uruchamianie bash w trybie POSIX wyłącza * niektóre * rozszerzenia, ale nie w żaden sposób nawet prawie wszystkie z nich. W związku z tym, chociaż ta odpowiedź jest poprawna pod względem tego, na co pozwala POSIX, jej rozumowanie nie wspiera tego bardzo skutecznie. –

15

Tak, jest to gramatyka powłoki POSIX. Można również mieć więcej niż jeden tutaj-doc dla tego samego polecenia (niektóre inne przykłady wykorzystania dwóch cat inwokacje, ale to działa tak samo):

cat <<EOF1 <<EOF2 
first here-doc 
EOF1 
second here-doc 
EOF2 

to wymyślił (przy użyciu 2 tutaj-docs dla stdin), ale jeśli myślisz o dostarczaniu danych wejściowych dla różnych deskryptorów plików, natychmiast ma to sens.

Istnieje również możliwość, aby upuścić cat całkowicie. Dlaczego nie zrobić tu-dokumentu bezpośrednio dostępne do cmd:

cmd << EOF 
input 
here 
EOF 
+0

'' ' cat << EOF1 << EOF2 pierwszy tu-doc EOF1 sekundy tutaj-doc EOF2 ' '' Powyższe nie działa. – user1424739

+0

@ user1424739 Działa w bieżącym zsh i bash. Popiół i ksh93 wydają się wyprowadzać tylko drugi tutaj dokument. – Jens

+0

Dlaczego upadek? Jeśli jest coś niedokładnego, proszę daj mi sposobność zaradzenia. – Jens

Powiązane problemy