Pregunta:
Digamos que tengo un script que quiero canalizar a otro comando o redirigir a un archivo (canalizar a sh
para los ejemplos). Suponga que estoy usando bash.
Podría hacerlo usando echo
:
echo "touch somefile
echo foo > somefile" | sh
También podría hacer casi lo mismo usando cat
:
cat << EOF
touch somefile
echo foo > somefile
EOF
Pero si reemplazo "EOF" por "EOF | sh", simplemente piensa que es parte del heredoc.
¿Cómo puedo hacer que cat
genere texto desde stdin y luego lo canalice a una ubicación arbitraria?
Respuesta:
Hay varias formas de hacer esto. El más simple es probablemente este:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
Otro, que es una sintaxis más agradable en mi opinión:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
Esto también funciona, pero sin la subcapa:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
Más variaciones:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
O:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
Por cierto, espero que el uso de cat
en su pregunta sea un marcador de posición para otra cosa. Si no, sácalo, así:
sh <<EOF
touch somefile
echo foo > somefile
EOF
Que podría simplificarse a esto:
sh -c 'touch somefile; echo foo > somefile'
o:
sh -c 'touch somefile
echo foo > somefile'
Redirigir la salida en lugar de la canalización
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
Usando cat
para obtener el equivalente de echo test > out
de echo test > out
:
cat >out <<EOF
test
EOF
Varios documentos aquí
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
Esto produce la salida:
hi
---
there
Esto es lo que está pasando:
- El shell ve el
( ... )
y ejecuta los comandos adjuntos en un subshell. - El gato y el eco son bastante simples. El
cat <&3
dice que se ejecute cat con el descriptor de archivo (fd) 0 (stdin) redirigido desde fd 3; en otras palabras, extraiga la entrada de fd 3. - Antes de que se inicie
(...)
, el shell ve los dos aquí redireccionamientos de documentos y sustituye fd 0 (<<EOF
) y fd 3 (3<<EOF2
) con el lado de lectura de las tuberías - Una vez que se inicia el comando inicial, el shell lee su stdin hasta que se alcanza EOF y lo envía al lado de escritura de la primera tubería
- A continuación, hace lo mismo con EOF2 y el lado de escritura de la segunda tubería.