2011-08-12 12 views
90

estoy familiarizado con esta sintaxis:Sintaxis de línea múltiple para canalizar un heredoc; es esto portable?

cmd1 << EOF | cmd2 
text 
EOF 

pero sólo descubrieron que fiesta me permite escribir:

cmd1 << EOF | 
text 
EOF 
cmd2 

(el heredoc se utiliza como entrada a cmd2). Esto parece una sintaxis muy extraña. ¿Es portátil?

+0

Vine aquí para encontrar una buena manera de dividir esta en varias líneas: 'big-largo comando1 con una gran cantidad de argumentos << EOF | big-long-command2 con muchos argumentos '. La "sintaxis impar" parece ser la mejor manera. – PaulC

+0

Un caso de uso conveniente para esto es cuando intenta convertir una tabla delimitada por espacios en una que está delimitada por tabulaciones para que pueda pegarla en las hojas de cálculo de Google. No tendrá que crear un archivo temporal. –

+0

La primera no funcionó para mí en z-shell. No me gusta el segundo porque aliena al | desde el comando, perdiendo el idioma (?) de las tuberías de concha. –

Respuesta

72

Sí, el estándar POSIX permite esto. According to the 2008 version:

El documento interno será tratada como una sola palabra que comienza después de la próxima <newline> y continúa hasta que hay una línea que contiene sólo el delimitador y una <newline>, sin <blank> caracteres entre ambas. Luego comienza el siguiente documento aquí, si hay uno.

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

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

lo que no hay problema en hacer cambios de dirección o tuberías. Su ejemplo es similar a algo como esto:

cat file | 
cmd 

Y la gramática cáscara (más abajo en la página del enlace) incluye las siguientes definiciones:

pipe_sequence :        command 
       | pipe_sequence '|' linebreak command 

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

lo tanto, un símbolo de canalización puede ser seguido por un End- de línea y todavía se considera parte de una tubería.

9

Hmm, supongo que sí, de acuerdo con la prueba en bash en modo POSIX:

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

funciona en 'dash' también –

+0

Una nota más: no coloque ningún espacio después del cierre 'EOF'. El mensaje se comportará de forma extraña y te preguntarás ¿qué diablos está mal? –

+0

Ejecutar bash en el modo POSIX apaga * algunas * extensiones, pero de ninguna manera, ni siquiera casi todas. Como tal, si bien esta respuesta es correcta en términos de lo que POSIX permite, su razonamiento no es muy eficaz. –

15

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

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

Esto se ideó (usando 2 aquí-docs para la entrada estándar), pero si piensas en proporcionar entradas para diferentes descriptores de archivos, tiene sentido de inmediato.

También existe la posibilidad de soltar el cat por completo. Por qué no hacer el aquí-documento directamente a disposición de cmd:

cmd << EOF 
input 
here 
EOF 
+0

'' ' cat << << EOF1 EOF2 por primera vez aquí-doc EOF1 segundo aquí-doc EOF2 ' '' Lo anterior no funciona. – user1424739

+0

@ user1424739 Funciona en zsh y bash actuales. La ceniza y ksh93 parecen dar salida solo al segundo documento aquí. – Jens

+0

¿Por qué el voto a favor? Si hay algo impreciso, por favor dame la oportunidad de remediarlo. – Jens

Cuestiones relacionadas