Apakah eval $ (nama file kucing) sama dengan nama file sumber?

9

Bekerja pada beberapa fungsi bash, saya tidak tahu source ...perintah, jadi saya menggunakannya eval $(cat ...)sebagai gantinya. Sekarang saya bertanya-tanya, apakah saya harus mengubah setiap penggunaan itu, atau apakah fungsinya sama?

Mereka tampaknya bekerja sama sekarang, tetapi mungkin akan ada beberapa perbedaan menyesatkan nanti, saya hanya ingin tahu.

Benjamin
sumber

Jawaban:

6

eval $(cat ...)tidak berfungsi dalam semua kasus. Misalnya, jeda baris dikonversi menjadi satu spasi $(cat ...)sebelum konten diproses oleh eval. Ini sering merusak pernyataan multi-baris seperti loop dan dokumen di sini.

Coba misalnya file berikut dengan kedua metode:

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

cat<<EOF
a
b
c
EOF
Florian Diesch
sumber
4
Jika Anda menggunakan tanda kutip, spasi putih akan tetap utuh:eval "$(cat file)"
glenn jackman
1
Ya, itu seharusnya berhasil juga. Tetapi jika seseorang harus mengubah kode pula saya lebih suka sourcekarena itu adalah perintah yang dibuat khusus untuk ini.
Florian Diesch
9

Seperti yang telah disebutkan oleh @glennjackman, Anda akan ingin mengutip substitusi perintah, jika tidak pemisahan kata dan perluasan pathname akan mengubah konten sebelum ia dieksekusi. Dan sementara keduanya akan menjalankan perintah dari file, ada perbedaan.

  • Saat Anda sumber skrip, berbagai variabel shell khusus akan dimodifikasi, terutama BASH_SOURCE, BASH_LINENOdan FUNCNAMEarray. Ini berguna untuk mencetak pesan kesalahan dan debugging.

  • Anda dapat kembali dari skrip bersumber dengan returnperintah ( help return). Dengan eval, Anda tidak akan mendapatkan efek itu. Dan juga perangkap RETURN tidak akan dipicu untuk eval.

  • Saat mengambil skrip, Anda bisa memberikan argumen padanya. Anda tidak dapat melakukan itu dengan eval itu.

  • Dengan eval, substitusi perintah akan membaca seluruh konten file ke dalam memori sebelum meneruskannya ke eval. Ketika Anda sumbernya, bash akan membaca dari file saat berjalan.

geirha
sumber
1

Ada ringkasan bagus dari sumber, eval dan eksekutif apa yang dilakukan di sini: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Saya pikir penggunaan eval dan sumber file Anda akan melakukan hal yang sama. Namun, saya tidak sepenuhnya yakin bahwa variabel di dalam subskrip akan berperilaku sama dalam hal apa pun. Saya akan merekomendasikan menggunakan sumber jika mungkin, karena ini adalah cara yang lebih mudah dan membuat kode Anda lebih mudah dibaca.

Hinz
sumber
3
comlineely tangential: bash memiliki singkatan untuk $(cat file)->$(< file)
glenn jackman