Isso funciona bem:
$ eval 'echo "1" > ~/Desktop/in/foo'
Mas não isso:
$ while IFS= read _cmd; do eval "$_cmd"; done < <(cat << EOF
'echo "1" > ~/Desktop/in/foo'
'echo "2" > ~/Desktop/in/bar'
EOF
)
bash: echo "1" > ~/Desktop/in/foo: No such file or directory
bash: echo "2" > ~/Desktop/in/bar: No such file or directory
Como corrigi-lo?
atualizar
Como sugerido, soltar aspas simples funciona, mas não para essa variação (idem colocando apenas o nome do arquivo entre aspas simples):
$ while IFS= read _cmd; do eval "$_cmd"; done < <(cat << EOF
echo "1" > ~/Desktop/in/foo (bis)
echo "2" > ~/Desktop/in/bar
EOF
)
Em conjunto com a solução fornecida:
"$SHELL" << EOF
echo "1" > ~/Desktop/in/'foo (bis)'
echo "2" > ~/Desktop/in/bar
EOF
Quando você executa
eval 'echo "1" > ~/Desktop/in/foo'
, o shell remove as aspas simples eeval
avaliaecho "1" > ~/Desktop/in/foo
.Quando você executa
eval "$_cmd"
(em seu código de pré-atualização), o shell se expande$_cmd
e remove as aspas duplas e, em seguida,eval
avalia'echo "1" > ~/Desktop/in/foo'
. Observe as aspas simples. Você não quereval
vê-los, remova-os do documento aqui.Em seu código atualizado, você provavelmente deseja
eval
avaliarecho "1" > ~/Desktop/in/'foo (bis)'
, portanto, use essa linha exata no documento aqui.Bem, "exato" não é a palavra certa em geral. Em geral
<< EOF
(ao contrário de, por exemplo,<< 'EOF'
) expande variáveis e poucas outras coisas no documento aqui (não há nenhuma em seu exemplo, mas em geral é assim que funciona). EntãoIFS= read _cmd
não éIFS= read -r _cmd
. Finalmenteeval
obtém uma string que não é necessariamente a string exata que você usou.Avaliar linha por linha impossibilita a avaliação de comandos de várias linhas.
A menos que você realmente queira confiar no que
<< EOF
eIFS= read
fazer com a(s) string(s) que você fornece (e você sabe o que está fazendo), apenas escreva o código diretamente no script. Afinal, você quer que o shell interpretando o script avalieecho "1" > ~/Desktop/in/foo
. Não é mesmo que você queira algum outro processo de shell. Não há necessidade de um documento aqui aqui.Acho que o código de pré-processamento para outro processo de shell pode fazer sentido (em alguns casos e quando você for cuidadoso), mas você deve usar, por exemplo
bash << EOF
, nãoread
.Outra coisa: o snippet
done < <(cat << EOF
pode ser simplificado paradone << EOF
(observe que essa alteração requer a remoção)
do final do seu código).