¿Es posible usar múltiples documentos aquí en bash?

14

¿Se pueden usar múltiples documentos aquí para proporcionar información a un comando en bash?

$ cat <<<foo <<<bar
bar
$ cat <<EOF1 <<EOF2
> foo
> EOF1
> bar
> EOF2
bar

Obviamente, en ambos casos, el segundo here-doc se usa como stdin y reemplaza la primera referencia. ¿Es la solución usar echos en su lugar?

$ cat <(echo -n foo) <(echo bar)
foobar

Además, por alguna razón, usar una combinación no funcionó para mí. ¿Por qué sería eso?

$ cat <<<foo <(echo bar)
bar
$ cat <(echo -n foo) <<<bar
foo
Gavilán
fuente
¿Hay alguna razón detrás del hecho de que desea utilizar dos documentos aquí en lugar de combinarlos en uno?
frijoles
1
@beans En realidad me encontré con esto cuando probé pastecon entradas ficticias. Supongo que puedo pensar en algunos otros escenarios. Si hubiera tenido un script con texto previamente manipulado en algunas variables, entonces podría querer hacer algo para ambos con un comando que solo toma archivos, por ejemplo diff.
Sparhawk
Otro caso de uso (me encontré con esto usando aquí-docs para crear un script de shell): usted quiere un par de líneas con la expansión de variables y luego algunas líneas sin: cat <<EOF1 <<"EOF2".
Toby Speight

Respuestas:

18

Tu puedes hacer:

cat /dev/fd/3 3<< E1 /dev/fd/4 4<< E2
foo
E1
bar
E2

Solo puede haber un stdin, ya que solo hay un descriptor de archivo 0.

cat << EOF
eof
EOF

es la abreviatura de:

cat /dev/fd/0 0<< EOF
eof
EOF

Y:

cat <<< foo

es:

cat /dev/fd/0 0<<< foo

Debe decidir qué abrir en el descriptor de archivo 0.

cat <(echo foo)

Es:

cat /dev/fd/123

Donde 123hay un descriptor de archivo para una tubería, y en paralelo, bash se ejecuta echo fooen otro proceso con el stdout redirigido al otro extremo de la tubería.

Una vez que pasa un nombre de archivo a cat, catya no lee de stdin. Necesitarías

cat <(echo foo) /dev/fd/0 << EOF
bar
EOF

O:

cat <(echo foo) - << EOF
bar
EOF

( -es decir catque lea de stdin).

Stéphane Chazelas
fuente
1
cat <<EOFno es exactamente lo mismo que cat /dev/fd/0...: en el último caso catve el nombre del archivo y lo abre.
Mikel
@Mikel, lo que quise decir es que es funcionalmente equivalente . Cuando no se pasa ningún argumento, se catlee desde su fd0, como si se pasara un argumento de -o /dev/fd/0(aunque en Linux (y solo en Linux), abrir /dev/fd/0no es exactamente como duplicar el descriptor de archivo 0).
Stéphane Chazelas
Me sorprendió mucho la /dev/fd/3 3<< E1construcción y ahora me pregunto qué son exactamente los elementos en / dev / fd /. Pensé que de alguna manera aparece mágicamente después de que el proceso abre un archivo en algún lugar del sistema de archivos con la excepción de 1 y 2, que están allí por defecto para cada proceso. Pero en su ejemplo, está utilizando el descriptor de archivo 3 y 4 que no está conectado a ningún archivo real, excepto para esa redirección de entrada. No puedo comprender eso en mi modelo mental de descriptores de archivos. ¿Qué pasa si el proceso quiere abrir otro archivo, sabría que tiene que usar fd 5? ¿Los fds tienen que ser 3, 4, 5 ... o pueden ser cualquier cosa?
calavera.info
@ calavera.info, parece que quieres crear una pregunta de seguimiento.
Stéphane Chazelas