Eval $ (cat filename) é o mesmo que o nome do arquivo de origem?

9

Trabalhando em algumas funções do bash, eu não sabia o source ...comando, então usei eval $(cat ...). Agora, estou me perguntando: se devo alterar todos os usos disso ou é apenas a mesma função?

Eles parecem funcionar da mesma forma agora, mas talvez haja algumas diferenças enganosas mais tarde, eu só quero saber.

Benjamin
fonte

Respostas:

6

eval $(cat ...)não funciona em todos os casos. Por exemplo, quebras de linha são convertidas em um único espaço $(cat ...)antes de o conteúdo ser processado eval. Isso geralmente quebra instruções com várias linhas, como loops e documentos aqui.

Tente, por exemplo, o seguinte arquivo com os dois métodos:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
Florian Diesch
fonte
4
Se você usar aspas, o espaço em branco irá permanecer intacta:eval "$(cat file)"
Glenn Jackman
1
Sim, isso deve funcionar também. Mas se alguém precisar alterar o código de qualquer maneira, prefiro source, pois é um comando feito especificamente para isso.
Florian Diesch 12/08/2012
9

Como já mencionado por @glennjackman, convém citar a substituição de comando, caso contrário, a divisão de palavras e a expansão do nome do caminho modificarão o conteúdo antes que ele seja avaliado. E enquanto ambos executam os comandos do arquivo, existem diferenças.

  • Quando você cria um script, várias variáveis ​​especiais do shell serão modificadas, principalmente as matrizes BASH_SOURCE, BASH_LINENOe FUNCNAME. Estes são úteis para imprimir mensagens de erro e depuração.

  • Você pode retornar de um script de origem com o returncomando ( help return). Com a avaliação, você não terá esse efeito. Da mesma forma, uma armadilha RETURN não será acionada para a avaliação.

  • Ao adquirir um script, você pode passar argumentos para ele. Você não pode fazer isso com essa avaliação.

  • Com o eval, a substituição do comando lê todo o conteúdo do arquivo na memória antes de passá-lo para o eval. Quando você o origina, o bash lê o arquivo à medida que avança.

Geirha
fonte
1

Há um bom resumo de qual fonte, eval e exec fazem aqui: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Eu acho que o uso de eval e source'ing no arquivo fará a mesma coisa. Não tenho certeza absoluta, porém, de que variáveis ​​dentro do subscrito se comportarão da mesma maneira em qualquer caso. Eu recomendo o uso da fonte, se possível, porque é o caminho mais direto a seguir e torna seu código mais legível.

Hinz
fonte
3
comletely tangencial: o bash tem um atalho para $(cat file)->$(< file)
glenn jackman