GNU/Linux >> Belajar Linux >  >> Linux

perintah eval di Bash dan kegunaannya yang khas

eval mengambil string sebagai argumennya, dan mengevaluasinya seolah-olah Anda mengetikkan string itu pada baris perintah. (Jika Anda meneruskan beberapa argumen, pertama-tama mereka digabungkan dengan spasi di antaranya.)

${$n} adalah kesalahan sintaks di bash. Di dalam kurung kurawal, Anda hanya dapat memiliki nama variabel, dengan beberapa kemungkinan awalan dan sufiks, tetapi Anda tidak dapat memiliki sintaks bash yang sewenang-wenang dan khususnya Anda tidak dapat menggunakan ekspansi variabel. Ada cara untuk mengatakan "nilai variabel yang namanya ada dalam variabel ini", meskipun:

echo ${!n}
one

$(…) menjalankan perintah yang ditentukan di dalam tanda kurung dalam subkulit (yaitu dalam proses terpisah yang mewarisi semua pengaturan seperti nilai variabel dari shell saat ini), dan mengumpulkan hasilnya. Jadi echo $($n) menjalankan $n sebagai perintah shell, dan menampilkan hasilnya. Sejak $n mengevaluasi ke 1 , $($n) mencoba menjalankan perintah 1 , yang tidak ada.

eval echo \${$n} menjalankan parameter yang diteruskan ke eval . Setelah perluasan, parameternya adalah echo dan ${1} . Jadi eval echo \${$n} menjalankan perintah echo ${1} .

Perhatikan bahwa sebagian besar waktu, Anda harus menggunakan tanda kutip ganda di sekitar penggantian variabel dan penggantian perintah (yaitu setiap kali ada $ ):"$foo", "$(foo)" . Selalu beri tanda kutip ganda di sekitar penggantian variabel dan perintah , kecuali Anda tahu bahwa Anda harus mengabaikannya. Tanpa tanda kutip ganda, shell melakukan pemisahan bidang (yaitu membagi nilai variabel atau output dari perintah menjadi kata-kata terpisah) dan kemudian memperlakukan setiap kata sebagai pola wildcard. Misalnya:

$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *

eval tidak terlalu sering digunakan. Di beberapa shell, penggunaan yang paling umum adalah untuk mendapatkan nilai variabel yang namanya tidak diketahui hingga runtime. Di bash, ini tidak perlu berkat ${!VAR} sintaksis. eval masih berguna saat Anda perlu membuat perintah yang lebih panjang yang berisi operator, kata khusus, dll.


Anggap saja eval sebagai "mengevaluasi ekspresi Anda sekali lagi sebelum dieksekusi"

eval echo \${$n} menjadi echo $1 setelah evaluasi putaran pertama. Tiga perubahan untuk diperhatikan:

  • \$ menjadi $ (Garis miring terbalik diperlukan, jika tidak maka akan mencoba mengevaluasi ${$n} , yang berarti sebuah variabel bernama {$n} , yang tidak diperbolehkan)
  • $n dievaluasi menjadi 1
  • eval menghilang

Di babak kedua, pada dasarnya adalah echo $1 yang dapat langsung dieksekusi.

Jadi eval <some command> pertama-tama akan mengevaluasi <some command> (yang saya maksud dengan mengevaluasi di sini adalah mengganti variabel, mengganti karakter yang lolos dengan yang benar, dll.), lalu menjalankan ekspresi yang dihasilkan sekali lagi.

eval digunakan ketika Anda ingin membuat variabel secara dinamis, atau membaca output dari program yang dirancang khusus untuk dibaca seperti ini. Lihat http://mywiki.wooledge.org/BashFAQ/048 untuk contoh. Tautan juga berisi beberapa cara umum yang digunakan eval digunakan, dan risiko yang terkait dengannya.


Menurut pengalaman saya, penggunaan eval yang "umum" adalah untuk menjalankan perintah yang menghasilkan perintah shell untuk menyetel variabel lingkungan.

Mungkin Anda memiliki sistem yang menggunakan kumpulan variabel lingkungan, dan Anda memiliki skrip atau program yang menentukan mana yang harus ditetapkan dan nilainya. Setiap kali Anda menjalankan skrip atau program, itu berjalan dalam proses bercabang, jadi apa pun yang dilakukannya langsung ke variabel lingkungan akan hilang saat keluar. Tetapi skrip atau program tersebut dapat mengirimkan perintah ekspor ke stdout.

Tanpa eval, Anda perlu mengarahkan ulang stdout ke file temp, sumber file temp, lalu menghapusnya. Dengan eval, Anda cukup:

eval "$(script-or-program)"

Perhatikan kutipan itu penting. Ambil contoh (buatan) ini:

# activate.sh
echo 'I got activated!'

# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")

$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!

Linux
  1. Perintah "eval" Di Bash?

  2. perintah ekspor bash

  3. perintah bash alias dengan tanda kutip tunggal dan ganda

  1. Dua kegunaan hebat untuk perintah cp:pintasan Bash

  2. Perbedaan Antara ' Dan ” Di Command Line (bash)??

  3. Mengapa eval harus dihindari di Bash, dan apa yang harus saya gunakan?

  1. Bash - Perintah tanggal dan spasi

  2. Jalankan perintah bash pada pipa jenkins

  3. Apa perbedaan antara &> dan >&di bash?