Existem várias maneiras de fazer isso. O mais simples é provavelmente isso:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
Outra, que é uma sintaxe melhor na minha opinião:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
Isso funciona também, mas sem o subnível:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
Mais variações:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
Ou:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
A propósito, espero que o uso de cat
em sua pergunta seja um espaço reservado para outra coisa. Se não, retire assim:
sh <<EOF
touch somefile
echo foo > somefile
EOF
O que poderia ser simplificado para isso:
sh -c 'touch somefile; echo foo > somefile'
ou:
sh -c 'touch somefile
echo foo > somefile'
Redirecionando a saída em vez de canalizar
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
Usando cat
para obter o equivalente a echo test > out
:
cat >out <<EOF
test
EOF
Vários documentos aqui
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
Isso produz a saída:
hi
---
there
Veja o que está acontecendo:
- O shell vê o
( ... )
e executa os comandos fechados em um subshell. - O gato e o eco são bastante simples. O
cat <&3
diz para executar o cat com o descritor de arquivo (fd) 0 (stdin) redirecionado do fd 3; em outras palavras, exclua a entrada do fd 3. - Antes de iniciar o
(...)
, o shell vê os dois documentos aqui redirecionados e substitui fd 0 (<<EOF
) e fd 3 (3<<EOF2
) pelo lado de leitura dos pipes - Depois que o comando inicial é iniciado, o shell lê seu stdin até que o EOF seja alcançado e envia isso para o lado da escrita do primeiro canal
- Em seguida, ele faz o mesmo com EOF2 e o lado da gravação do segundo tubo