web-dev-qa-db-fra.com

Syntaxe multiligne pour canaliser un hérédoc; est-ce portable?

Je connais cette syntaxe:

cmd1 << EOF | cmd2
text
EOF

mais je viens de découvrir que bash me permet d'écrire:

cmd1 << EOF |
text
EOF
cmd2

(l'hérédoc est utilisé comme entrée de cmd1 et la sortie de cmd1 est redirigée vers cmd2). Cela semble être une syntaxe très étrange. Est-ce portable?

118
William Pursell

Oui, le standard POSIX le permet. Selon la version 2008:

Le document ci-dessous doit être traité comme un seul mot qui commence après le prochain <newline> et continue jusqu'à ce qu'il y ait une ligne contenant uniquement le délimiteur et un <newline>, sans <blank> caractères entre les deux. Ensuite, le prochain document ici commence, s'il y en a un.

Et inclut cet exemple de plusieurs "documents ici" dans la même ligne:

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

Il n'y a donc aucun problème à faire des redirections ou des tuyaux. Votre exemple est similaire à quelque chose comme ceci:

cat file |
cmd

Et la grammaire de Shell (plus bas sur la page liée) inclut ces définitions:

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command

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

Ainsi, un symbole de tuyau peut être suivi d'une fin de ligne et être toujours considéré comme faisant partie d'un pipeline.

92
Ned Deily

Oui, c'est dans la grammaire du shell POSIX. Vous pouvez également avoir plus d'un document ici pour la même commande (certains autres exemples utilisent deux invocations cat, mais cela fonctionne aussi):

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

C'est artificiel (en utilisant 2 here-docs pour stdin), mais si vous pensez fournir une entrée pour différents descripteurs de fichiers, cela a immédiatement du sens.

Il y a aussi la possibilité de supprimer complètement le cat. Pourquoi ne pas mettre le document ici directement à la disposition de cmd:

cmd << EOF
input
here
EOF
21
Jens

Hmm, je suppose que oui, selon le test de bash en mode POSIX:

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

Salut, vérifiez cela, par exemple

#!/bin/sh
( base32 -d | base64 -d )<<ENDOFTEXT
KNDWW42DNNSHS5ZXPJCG4MSVM5MVQVT2JFCTK3DELBFDCY2IIJYGE2JUJNHWS22LINVHQMCMNVFD
CWJQIIZVUV2JOVNEOVJLINTW6PIK
ENDOFTEXT

salutations

1
buc