151 votes

Syntaxe multiligne pour le piping d'un heredoc ; est-ce portable ?

Cette syntaxe m'est familière :

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 envoyée à cmd2). Cela semble être une syntaxe très étrange. Est-elle portable ?

0 votes

Je suis venu ici pour trouver un bon moyen de diviser ceci en plusieurs lignes : big-long-command1 with lots of args << EOF | big-long-command2 with lots of args . La "syntaxe bizarre" semble être la meilleure solution.

0 votes

Un cas d'utilisation pratique est celui où vous essayez de convertir un tableau délimité par des espaces en un tableau délimité par des tabulations afin de pouvoir le coller dans Google Spreadsheets. Vous n'aurez pas à créer de fichier temporaire.

0 votes

Le premier n'a pas fonctionné pour moi dans z-shell. Je n'aime pas la 2ème parce qu'elle aliène le | de la commande, perdant l'idiome ( ?) des pipelines shell.

117voto

Ned Deily Points 40248

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

Le document ici présent est traité comme un mot unique qui commence après le mot suivant <newline> et continue jusqu'à ce qu'il y ait une ligne contenant seulement le délimiteur et un <newline> sans <blank> des personnages entre les deux. Ensuite, le document suivant commence, s'il y en a un.

Et comprend 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 pour faire des redirections ou des tuyaux. Votre exemple ressemble à quelque chose comme ceci :

cat file |
cmd

Et la grammaire de l'interpréteur de commandes (plus bas sur la page liée) comprend 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 considéré comme faisant partie d'un pipeline.

28voto

Jens Points 17702

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

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

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

Il y a aussi la possibilité de laisser tomber le cat entièrement . Pourquoi ne pas mettre le document ici directement à la disposition de cmd :

cmd << EOF
input
here
EOF

1 votes

``` cat <<EOF1 <<EOF2 first here-doc EOF1 second here-doc EOF2 ``` Ce qui précède ne fonctionne pas.

0 votes

@user1424739 Cela fonctionne dans les versions actuelles de zsh et bash. Les ash et ksh93 semblent ne sortir que le second doc ici.

0 votes

Pourquoi le downvote ? S'il y a quelque chose d'inexact, donnez-moi l'occasion d'y remédier.

18voto

TMS Points 17522

Hmm, je suppose que oui, d'après le test dans bash en mode POSIX :

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

0 votes

Une autre petite remarque : ne mettez pas d'espace après la fermeture. EOF . L'invite se comportera bizarrement et vous vous demanderez ce qui ne va pas.

2 votes

L'exécution de bash en mode POSIX coupe l'alimentation en électricité. algunos des extensions, mais en aucun cas de la quasi-totalité d'entre elles. En tant que telle, bien que cette réponse soit correcte en termes de ce que POSIX permet, son raisonnement ne soutient pas cela très efficacement.

3voto

buc Points 31

Bonjour, vérifiez ceci, par exemple

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

salutations

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X