Cara menggunakan EVAL di skrip Bash Linux

Fatmawati Ahmad zaenuri / Shutterstock.com

Dari semua perintah bash, kamu orang tua yang malang eval Mungkin dia memiliki reputasi terburuk. Jurnalisme yang baik atau jurnalisme yang buruk? Kami membahas penggunaan dan risiko dari perintah Linux yang kurang umum ini.

Kita perlu bicara tentang Eva

digunakan sembarangan eval Ini dapat menyebabkan perilaku yang tidak terduga dan bahkan ketidakamanan sistem. Tampaknya bijaksana bahwa kita mungkin tidak boleh menggunakannya, bukan? Tidak memadai.

Hal yang sama dapat dikatakan tentang mobil. Di tangan yang salah, mereka adalah senjata mematikan. Manusia menggunakannya dalam serangan run-down dan sebagai kendaraan pelarian. Haruskah kita semua menyerah pada mobil? Tidak, tentu saja tidak. Tetapi harus digunakan dengan benar dan oleh orang yang tahu cara mengendarainya.

Kata sifat yang biasa berlaku untuk eval Buruk. “Tapi itu semua tergantung pada bagaimana Anda menggunakannya. Ini eval Perintah mengurutkan file Nilai dari satu atau lebih variabel. Membuat rantai perintah. Kemudian perintah ini dijalankan. Ini membuatnya berguna saat Anda perlu menangani situasi di mana konten perintah disimpulkan secara dinamis saat skrip sedang berjalan.

Masalah muncul saat menulis teks untuk digunakan eval Di saluran yang diterima dari suatu tempat luar skenario. Itu dapat dimasukkan oleh pengguna, dikirim melalui API, ditautkan ke permintaan HTTPS, atau digunakan di tempat lain di luar skrip.

Jika string itu eval Ini berfungsi, tidak diturunkan secara lokal dan terprogram, ada risiko bahwa string mungkin berisi instruksi sebaris berbahaya atau input cacat lainnya. Anda jelas tidak menginginkan itu eval Jalankan perintah berbahaya. Jadi jangan menggunakannya untuk berada di sisi yang aman eval Dengan string yang dihasilkan secara eksternal atau input pengguna.

Mulai peringkat

ini eval Perintahnya adalah perintah shell bash sebaris. Jika bash hadir, eval akan ada.

eval Parameter digabungkan menjadi satu string. Satu spasi digunakan untuk memisahkan elemen gabungan. Ini mengevaluasi argumen dan kemudian meneruskan seluruh string ke shell untuk dieksekusi.

Mari kita buat sebuah variabel bernama wordcount.

wordcount="wc -w raw-notes.md"

Variabel String berisi perintah jumlah kata dalam file bernama raw-notes.md.

kita bisa menggunakan eval Untuk menjalankan perintah ini dengan melewatkannya evaluasi variabel.

Perintah dijalankan di shell saat ini, bukan di subset. Kita bisa menunjukkannya dengan mudah. Kami memiliki file teks pendek yang disebut “variables.txt”. Ini berisi dua baris ini.

first=How-To
second=Geek

kita akan menggunakan cat Untuk mengirim baris ini ke jendela terminal. Kemudian kita akan menggunakan eval kecepatan cat Perintah untuk menjalankan instruksi dalam file teks. Ini menetapkan variabel untuk kita.

cat variables.txt
eval "$(cat variables.txt)"
echo $first $second

Terima kasih atas usahanya echo Untuk mencetak nilai dari variabel, kita dapat melihat bahwa eval Perintah dijalankan di shell saat ini, bukan di subset.

Proses dalam koleksi anak tidak dapat mengubah lingkungan shell dari proses induk. Karena EVAL berjalan di shell saat ini, variabel ditetapkan oleh eval Itu dapat digunakan secara kebetulan yang dimulai pada eval Memerintah.

Ingatlah hal ini saat menggunakan eval Dalam skrip, untuk mengubah sampul eval Ini adalah subset di mana skrip berjalan, bukan shell yang memulainya.

terkait: Cara menggunakan perintah cat dan tac Linux

Menggunakan variabel dalam rantai perintah

Kita dapat memasukkan variabel lain dalam string perintah. Kami akan mendefinisikan dua variabel yang berisi bilangan bulat.

num1=10 
num2=7

Kami membuat variabel yang berisi expr Perintah yang mengembalikan jumlah dua angka. Ini berarti bahwa kita perlu mengakses nilai dua variabel integer dalam perintah. Perhatikan backtick tentang expr untuk mengekspresikan.

add="`expr $num1 + $num2`"

Mari buat perintah lain untuk menunjukkan kepada kita hasilnya expr untuk mengekspresikan.

show="echo"

Perhatikan bahwa kita tidak perlu menambahkan spasi di akhir echo String, selalu di awal expr Garis. eval jaga dirimu

Untuk menjalankan seluruh perintah yang kami gunakan:

eval $show $add

nilai variabel dalam expr Senar diganti dengan eval sebelum meneruskannya ke shell untuk dieksekusi.

terkait: Cara bekerja dengan variabel di Bash

Mengakses variabel dalam variabel

Anda dapat menetapkan nilai ke variabel dan kemudian menetapkan nama keluarga variabel ini ke variabel lain. menggunakan evalAnda bisa mencapainya evaluasi Itu diadakan di variabel pertama, dengan namanya, yaitu evaluasi disimpan dalam variabel kedua. Sebuah contoh akan membantu Anda memperjelas hal ini.

Salin skrip ini ke editor dan simpan ke file bernama assign.sh.

#!/bin/bash

title="How-To Geek"
webpage=title
command="echo"
eval $command ${$webpage}

Kita perlu membuatnya dapat dieksekusi dengan ekstensi chmod Memerintah.

chmod +x assign.sh

Ini harus dilakukan untuk semua skrip yang Anda salin dari artikel ini. Cukup gunakan nama skrip yang sesuai dalam setiap kasus.

Saat kami menjalankan skrip kami, kami melihat skrip yang diubah title meskipun eval Perintah variabel digunakan webpage.

./assign.sh

tanda dolar buronan$“dan kawat gigi”{}“Memaksa evaluasi untuk memeriksa nilai variabel yang namanya disimpan.” webpage Pekerja.

Gunakan variabel yang dihasilkan secara dinamis

kita bisa menggunakan eval Buat variabel secara dinamis. Skrip ini disebut “loop.sh”.

#!/bin/bash

total=0
label="Looping complete. Total:"

for n in {1..10}
do
  eval x$n=$n
  echo "Loop" $x$n
  ((total+=$x$n))
done

echo $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 $x10

echo $label $total

Membuat variabel yang disebut total yang berisi jumlah nilai dari variabel yang kita buat. Kemudian itu membuat variabel string bernama label. Ini adalah string teks sederhana.

Kami mengulang melalui 10 loop dan membuat 10 variabel bernama x1 sampai x10. ini eval Pernyataan di badan loop mengembalikan “x” dan mengambil nilai penghitung loop $n untuk membuat nama variabel. Pada saat yang sama, ia menetapkan variabel baru ke nilai penghitung loop $n.

Ini mencetak variabel baru di jendela terminal dan kemudian bertambah total Sebuah variabel dengan nilai dari variabel baru.

Di luar loop, 10 variabel baru dicetak ulang, semuanya dalam satu baris. Perhatikan bahwa kita juga dapat merujuk ke variabel dengan nama sebenarnya tanpa menggunakan versi yang dihitung atau diturunkan dari nama mereka.

Akhirnya, kami menunjukkan nilai total Pekerja.

./loop.sh

terkait: Primer: Bash Loop: Untuk, Sementara, dan Sampai

Menggunakan Eval dengan Array

Pertimbangkan skenario di mana Anda memiliki skrip yang berjalan untuk waktu yang lama dan melakukan beberapa pemrosesan untuk Anda. Menulis ke file log dengan nama yang dibuat dari stempel waktu. Terkadang file log baru dibuat. Ketika skrip selesai dan tidak ada kesalahan, file log yang dibuat dihapus.

Mereka tidak menginginkannya dengan mudah rm *.logAnda hanya ingin menghapus file log yang dibuatnya. Script ini mensimulasikan fungsi ini. Ini adalah clear-logs.sh.

#!/bin/bash

declare -a logfiles

filecount=0 
rm_string="echo"

function create_logfile() {
  ((++filecount))
  filename=$(date +"%Y-%m-%d_%H-%M-%S").log
  logfiles[$filecount]=$filename
  echo $filecount "Created" ${logfiles[$filecount]}
}

# body of the script. Some processing is done here that
# periodically generates a log file. We'll simulate that
create_logfile
sleep 3
create_logfile
sleep 3
create_logfile
sleep 3
create_logfile

# are there any files to remove?
for ((file=1; file<=$filecount; file++))
do
  # remove the logfile
  eval $rm_string ${logfiles[$file]} "deleted..."
  logfiles[$file]=""
done

Script mendeklarasikan array bernama logfiles . Ini berisi nama file log yang dihasilkan oleh skrip. Mendeklarasikan variabel yang disebut filecount . Ini berisi jumlah file log yang telah dibuat.

Itu juga mengumumkan seri yang disebut rm_string. Dalam teks nyata, ekstensi ini akan mencakup rm permintaan tetapi kami menggunakan echo Hal ini memungkinkan kita untuk membuktikan prinsip non-destruktif.

Fungsi create_logfile() Di sinilah setiap file log diberi nama dan akan dibuka. Kami hanya membuat ini nama filedan berpura-pura bahwa itu dibuat di sistem file.

Fungsinya meningkat filecount Pekerja. Nilai awalnya adalah nol, jadi nama file pertama yang kita buat akan disimpan di posisi pertama dalam array. Itu dilakukan dengan sengaja, lihat di bawah.

Nama file dibuat dengan ekstensi date ekstensi perintah dan registri. Nama disimpan dalam array pada posisi yang ditentukan oleh filecount. Nama ditampilkan di jendela stasiun. Dalam skrip asli Anda juga dapat membuat file yang sebenarnya.

Bagian utama dari teks disimulasikan dengan sleep Memerintah. Itu membuat file log pertama, menunggu tiga detik, dan kemudian membuat yang lain. Ini menciptakan empat file log yang didistribusikan sehingga stempel waktu nama file berbeda.

Akhirnya ada loop yang menghapus file log. File penghitung loop diatur ke satu. Ini dihitung termasuk nilai filecountYang berisi jumlah file yang telah dibuat.

jika filecount Itu selalu disetel ke nol karena tidak ada file log yang dibuat, dan badan perulangan tidak pernah dieksekusi karena satu tidak kurang dari atau sama dengan nol. Oleh karena itu, filecount Variabel disetel ke nol saat dideklarasikan dan alasan untuk meningkatkannya Sebelum File pertama telah dibuat.

Di dalam loop yang kami gunakan eval dengan non-destruktif rm_string dan nama file yang diekstrak dari array. Selanjutnya, kita mengatur elemen array ke string kosong.

Inilah yang kami lihat ketika kami menjalankan skrip.

./clear-logs.sh

Semuanya tidak buruk

banyak fitnah eval Itu pasti ada kegunaannya. Seperti kebanyakan alat, menggunakannya sembarangan berbahaya, dan dalam lebih dari satu cara.

Jika Anda memastikan bahwa string yang sedang Anda kerjakan dibuat secara internal dan tidak ditangkap oleh manusia, API, atau hal-hal seperti permintaan HTTPS, Anda akan menghindari jebakan terbesar.

terkait: Cara menampilkan tanggal dan waktu di Terminal Linux (dan menggunakannya dalam skrip Bash)

Baca Juga!

Google optimis bahwa Pixel 7 akan menjadi peluncuran terbesarnya

Ryan Haines / Otoritas Android TL; Dr Google dikatakan yakin bahwa seri Pixel 7 akan …