Řekněme, že mám skript, který chci přesměrovat na jiný příkaz nebo přesměrovat do souboru (napojení na sh
pro příklady). Předpokládejme, že používám bash.
Mohl bych to udělat pomocí echo
:
echo "touch somefile
echo foo > somefile" | sh
Mohl bych také udělat téměř totéž pomocí cat
:
cat << EOF
touch somefile
echo foo > somefile
EOF
Ale pokud nahradím „EOF“ za „EOF | sh“ prostě si myslí, že je součástí heredoc.
Jak to udělat, aby cat
vypíše text z stdin a poté jej převede do libovolného umístění?
Přijatá odpověď:
Existuje několik způsobů, jak to udělat. Nejjednodušší je asi toto:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
Další, podle mého názoru hezčí syntaxe:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
Toto funguje také, ale bez subshell:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
Další varianty:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
Nebo:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
Mimochodem, očekávám použití cat
ve vaší otázce je zástupný symbol pro něco jiného. Pokud ne, vyjměte to takto:
sh <<EOF
touch somefile
echo foo > somefile
EOF
Což by se dalo zjednodušit na toto:
sh -c 'touch somefile; echo foo > somefile'
nebo:
sh -c 'touch somefile
echo foo > somefile'
Přesměrování výstupu namísto potrubí
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
Pomocí cat
získat ekvivalent echo test > out
:
cat >out <<EOF
test
EOF
Více dokumentů zde
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
Tím vznikne výstup:
hi
---
there
Zde je to, co se děje:
- Shell vidí
( ... )
a spouští přiložené příkazy v subshell. - Kočka a echo jsou dostatečně jednoduché.
cat <&3
říká spustit cat s deskriptorem souboru (fd) 0 (stdin) přesměrovaným z fd 3; jinými slovy, vyřadit vstup z fd 3. - Před
(...)
je spuštěn, shell vidí dvě zde přesměrování dokumentu a nahradí fd 0 (<<EOF
) a fd 3 (3<<EOF2
) se čtenou stranou potrubí - Jakmile je spuštěn počáteční příkaz, shell čte svůj stdin, dokud není dosaženo EOF, a posílá jej na zapisovací stranu prvního roura
- Dále provede to samé s EOF2 a zapisovací stranou druhé roury