bash shell pipe sh heredoc

bash - Sintaxis multilínea para canalizar un heredoc; es esto portable?



heredoc bash (3)

Estoy familiarizado con esta sintaxis:

cmd1 << EOF | cmd2 text EOF

pero acaba de descubrir que bash me permite escribir:

cmd1 << EOF | text EOF cmd2

(el heredoc se usa como entrada para cmd1, y la salida de cmd1 se canaliza a cmd2). Esto parece una sintaxis muy extraña. ¿Es portátil?


Hmm, supongo que sí, según la prueba en bash en modo POSIX:

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


Sí, el estándar POSIX lo permite. De acuerdo con la versión de 2008:

El documento aquí se tratará como una sola palabra que comienza después de la siguiente <newline> y continúa hasta que haya una línea que contenga solo el delimitador y una <newline> , sin caracteres <blank> en el medio. Luego comienza el siguiente documento aquí, si hay uno.

E incluye este ejemplo de múltiples "documentos aquí" en la misma línea:

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

Entonces no hay problema haciendo redirecciones o tuberías. Tu ejemplo es similar a algo como esto:

cat file | cmd

Y la gramática de shell (más abajo en la página enlazada) incluye estas definiciones:

pipe_sequence : command | pipe_sequence ''|'' linebreak command newline_list : NEWLINE | newline_list NEWLINE ; linebreak : newline_list | /* empty */

Entonces un símbolo de tubería puede ser seguido por un final de línea y aún ser considerado parte de una tubería.


Sí, está en la gramática de shell POSIX. También puede tener más de un aquí-doc para el mismo comando (algunos otros ejemplos usan dos invocaciones de cat , pero esto también funciona):

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

Esto es inventado (usando 2 here-docs para stdin), pero si piensas en proporcionar entradas para diferentes descriptores de archivos, tiene sentido de inmediato.

También existe la posibilidad de dejar caer al cat completo . ¿Por qué no hacer el documento aquí directamente disponible para cmd :

cmd << EOF input here EOF