Diciamo che ho uno script che voglio reindirizzare a un altro comando o reindirizzare a un file (piping a sh
per gli esempi). Supponiamo che io stia usando bash.
Potrei farlo usando echo
:
echo "touch somefile
echo foo > somefile" | sh
Potrei anche fare quasi la stessa cosa usando cat
:
cat << EOF
touch somefile
echo foo > somefile
EOF
Ma se sostituisco “EOF” con “EOF | sh" pensa solo che faccia parte dell'heredoc.
Come posso fare in modo che cat
restituisce il testo da stdin e quindi lo reindirizza a una posizione arbitraria?
Risposta accettata:
Ci sono diversi modi per farlo. Il più semplice è probabilmente questo:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
Un altro, che è una sintassi più bella secondo me:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
Funziona anche così, ma senza la subshell:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
Altre varianti:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
Oppure:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
A proposito, mi aspetto l'uso di cat
nella tua domanda c'è un segnaposto per qualcos'altro. In caso contrario, tiralo fuori, in questo modo:
sh <<EOF
touch somefile
echo foo > somefile
EOF
Che potrebbe essere semplificato in questo modo:
sh -c 'touch somefile; echo foo > somefile'
oppure:
sh -c 'touch somefile
echo foo > somefile'
Reindirizzamento dell'output invece del piping
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
Usando cat
per ottenere l'equivalente di echo test > out
:
cat >out <<EOF
test
EOF
Più documenti qui
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
Questo produce l'output:
hi
---
there
Ecco cosa sta succedendo:
- La shell vede il
( ... )
ed esegue i comandi inclusi in una subshell. - Il gatto e l'eco sono abbastanza semplici. Il
cat <&3
dice di eseguire cat con il descrittore di file (fd) 0 (stdin) reindirizzato da fd 3; in altre parole, elimina l'input da fd 3. - Prima del
(...)
viene avviato, la shell vede i due qui document reindirizza e sostituisce fd 0 (<<EOF
) e fd 3 (3<<EOF2
) con il lato lettura dei tubi - Una volta avviato il comando iniziale, la shell legge il suo stdin finché non viene raggiunto EOF e lo invia al lato di scrittura della prima pipe
- Successivamente, fa lo stesso con EOF2 e il lato di scrittura della seconda pipe