Parsing variabel yang benar dan mengutip dalam bash

Parsing variabel yang benar dan mengutip dalam bash

Mengutip salah dalam kode sumber asli dapat dengan mudah mengarah ke bug ketika input yang disediakan oleh pengguna tidak seperti yang diharapkan atau tidak seragam. Seiring waktu, ketika skrip bash berubah, efek samping yang tidak terduga dari variabel yang dikutip secara tidak benar dapat menyebabkan bug bahkan dalam kode yang tidak tersentuh. Ini bahkan lebih penting untuk aplikasi terkait keamanan yang mungkin rentan terhadap upaya peretasan. Pelajari cara melakukan pengutipan dan penguraian/validasi variabel dengan benar sejak awal, dan hindari banyak masalah ini! Mari kita mulai…

Dalam seri tutorial ini Anda akan belajar:

  • Cara mengutip variabel bash Anda dengan benar
  • Peringatan dan hasil dari kutipan yang salah
  • Bagaimana memastikan nilai variabel adalah apa yang seharusnya
  • Cara memeriksa nilai variabel kosong, numerik dan teks
Parsing variabel yang benar dan mengutip dalam bash

Persyaratan dan konvensi perangkat lunak yang digunakan

Persyaratan Perangkat Lunak dan Konvensi Baris Perintah Linux
Kategori Persyaratan, konvensi atau versi perangkat lunak yang digunakan
Sistem Distribusi Linux-independen
Perangkat lunak Baris perintah bash, sistem berbasis Linux
Lainnya Utilitas apa pun yang tidak termasuk dalam shell bash secara default dapat diinstal menggunakan sudo apt-get install-name utilitas (atau yum bukannya apt-get)
Konvensi # - mengharuskan Linux -Commands untuk dieksekusi dengan hak istimewa root baik secara langsung sebagai pengguna root atau dengan menggunakan sudo memerintah
$-mengharuskan Linux-Commands untuk dieksekusi sebagai pengguna biasa

Contoh 1: Mengutip variabel -variabel tersebut!

Kecuali jika Anda bekerja dengan nilai-nilai numerik, dan bahkan dalam hal ini pada waktu itu, adalah bijaksana untuk selalu mengutip variabel berbasis teks Anda saat memeriksa kesetaraan dll. Mari kita lihat contoh:

$ Var1 = "a"; if [$ var1 == "a"]; Lalu echo 'ya!'; fi ya! $ Var1 =; if [$ var1 == "a"]; Lalu echo 'ya!'; fi bash: [: ==: operator unary diharapkan 


Pertama kami mengatur Var1 untuk nilainya A dan kemudian memeriksa jika Var1 sama A. Itu berhasil, dan kami mungkin berpikir kode kami baik-baik saja dan meninggalkannya apa adanya di dalam skrip kami. Namun, beberapa saat kemudian dan setelah banyak perubahan kode, kami mulai melihat bash: [: ==: operator unary diharapkan - Pesan yang agak samar yang memberi tahu kami ada sesuatu yang salah dengan kode kami.

Alasannya ditampilkan dalam contoh kedua. Jika entah bagaimana variabel kami kosong, saya.e. telah gagal diatur dengan benar (atau telah dihapus sejak pengaturan), maka kita akan disajikan dengan kesalahan karena Bash secara efektif membaca ini; if [== "a"] yang merupakan pernyataan yang tidak masuk akal, dan gagal menghitung.

Jika kami mengutip variabel kami dengan benar dengan kutipan ganda ("), ini tidak akan terjadi:

$ Var1 =; if ["$ var1" == "a"]; Lalu echo 'ya!'; fi $ 

Kali ini, Bash membaca pernyataan itu Jika ["" == "A"] - Pernyataan lebih mudah di mata dan kompiler bash. Tidak ada output yang dihasilkan dengan jelas string kosong tidak sama dengan huruf A.

Contoh 2: Mengambil kutipan sedikit lebih jauh

Setelah Anda bekerja dengan Bash untuk sementara waktu, Anda akan mempelajari beberapa idiom bahasa. Salah satu idiom seperti itu adalah - sebut saja hak istimewa (dan itu pasti kenyamanan!) - Untuk dapat mengutip variabel numerik bahkan jika operasi numerik dieksekusi:

$ Var1 = 13; if ["$ var1" -eq 13]; Lalu echo 'ya!'; fi ya! $ Var1 = 7; if ["$ var1" -eq 13]; Lalu echo 'ya!'; fi 

Meskipun VAR1 diatur ke nilai numerik, Bash akan menerima " mengutip sekitar var1 dan dengan benar menghasilkan hasil pernyataan if menggunakan sama (Saya.e. -Persamaan) Operasi perbandingan.

Namun, kami belum mencapai lingkaran penuh, karena berikut ini masih gagal;

$ Var1 =; if ["$ var1" -eq 13]; Lalu echo 'ya!'; fi bash: [:: ekspresi integer diharapkan 

Kali ini ekspresi integer diharapkan, namun variabel kosong (i.e. "" disahkan), dan ini tentu saja bukan numerik. Apakah ada cara untuk memperbaikinya? Tentu:

Contoh 3: Memeriksa panjang nol

$ Var1 =; if [-n "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi $ var1 = 13; if [-n "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi ya! 

Di sini kami menggunakan pra-cek untuk melihat apakah variabel tidak memiliki panjang nol dengan menggunakan pernyataan bersyarat -N yang berarti itu String tidak memiliki panjang nol. Ini juga bisa ditukar dengan terbalik dengan menggunakan ! -z Di mana -z cara String memiliki panjang nol dan ! meniadakan hal yang sama, saya.e. membalikkan hasilnya:

$ Var1 =; jika [ ! -z "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi $ var1 = 13; jika [ ! -z "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi ya! $ Var1 = 7; jika [ ! -z "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi $ 


Kami juga menambahkan = 7 Contoh di sini untuk menunjukkan bagaimana jika Fungsi pernyataan dengan benar. Selalu uji Anda jika pernyataan dan kondisi dalam berbagai situasi, kasus penggunaan dan pengecualian umum (nilai buruk, tidak ada nilai, nilai ganjil, dll.) Jika Anda ingin memastikan kode Anda akan bebas dari bug.

Contoh 4: cek yang hampir lengkap

Masih ada kekurangan dalam contoh terakhir. Apakah Anda mengambilnya? Pada dasarnya, jika kita memberikan nilai tekstual ke string, atau jika Pernyataan masih gagal:

$ Var1 = "a"; jika [ ! -z "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi bash: [: a: ekspresi integer diharapkan 

Ini bisa diatasi dengan menggunakan subshell, grep, dan beberapa ekspresi reguler. Untuk informasi lebih lanjut tentang ekspresi reguler, lihat Bash Regexps kami untuk pemula dengan contoh dan lanjutan Bash Regex dengan contoh artikel. Untuk informasi lebih lanjut tentang subshells bash, lihat subshells Linux kami untuk pemula dengan contoh dan subshell Linux canggih dengan contoh artikel.

Sintaksnya tidak terlalu rumit:

$ Var1 = 7; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi $ var1 = 13; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi ya! $ Var1 = "a"; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; fi $ 

Besar. Di sini kami memeriksa isinya Var1 menjadi numerik dengan menggunakan a grep -o (hanya grep; i.e. grep hanya bagian yang cocok dengan string pencarian, yang dalam hal ini adalah ekspresi reguler). Kami memilih karakter apa pun dari 0-9 dan ini satu kali atau lebih (seperti yang ditunjukkan oleh \+ Kualifikasi ke [0-9] rentang seleksi). Lalu, kami mencoba dan mencocokkan ini Grep hanya cocok dengan bagian teks terhadap variabel asli. Apakah itu sama? Jika ya, maka variabel kami hanya terdiri dari angka.

Saat kami memperluas luar kami jika pernyataan sedikit untuk memasukkan kalau tidak Klausa yang akan memberi tahu kita jika suatu variabel tidak numerik, dan ketika kita mencoba dan meneruskan 'A' Sebagai input, kita melihat bahwa berbagai input masing -masing diuraikan dengan benar;

$ Var1 = 7; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; lain variabel gema tidak numerik!'; fi $ var1 = 13; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; lain variabel gema tidak numerik!'; fi ya! $ Var1 = "a"; if ["$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; lain variabel gema tidak numerik!'; variabel fi bukan numerik! 


Jadi sekarang kami memiliki baris yang sempurna untuk kode kami, tidak? Tidak ... kami masih melewatkan sesuatu ... apakah Anda melihat apa?

Contoh 5: cek lengkap

Apakah Anda melihat masalahnya? Kami belum memeriksa variabel kosong!

$ Var1 = "; if [" $ (echo "$ var1" | grep -o '[0-9] \+') "==" $ var1 "]; lalu jika [" $ var1 "-eq 13]; lalu gema 'ya!'; fi; lain variabel gema tidak numerik!'; fi bash: [:: ekspresi integer diharapkan 

Aduh. Saya percaya sekarang Anda melihat mengapa saya secara teratur menyebutkan dalam artikel saya untuk selalu memeriksa kreasi kode Anda dengan satu atau lain cara. Tentu, Bash cocok untuk skrip cepat dan mudah, tetapi jika Anda ingin memastikan semuanya akan terus bekerja dengan baik saat mengubah skrip Anda atau menambahkan kode tambahan, Anda ingin memastikan tes, input, dan output Anda bersih dan jelas ditentukan dengan jelas dengan jelas dengan jelas dengan jelas dengan jelas dengan jelas. Perbaikannya mudah:

$ Var1 = "; jika [ ! -z "$ var1" -a "$ (echo" $ var1 "| grep -o '[0-9] \+')" == "$ var1"]; Kemudian jika ["$ var1" -eq 13]; Lalu echo 'ya!'; fi; lain variabel gema tidak numerik!'; variabel fi bukan numerik! 

Di sini, menggunakan kepalan tangan jika pernyataan, kami menambahkan kondisi tambahan untuk variabel Var1 untuk tidak (!) menjadi variabel panjang nol. Ini berfungsi dengan baik mengingat pengaturan saat ini sebagai bagian kedua dari yang pertama jika Pernyataan masih dapat berjalan terlepas dari isi Var1.

Kesimpulan

Dalam artikel ini, kami melihat bagaimana cara mengutip dan menguraikan/mengevaluasi variabel dengan benar, dan kami mengeksplorasi betapa rumitnya untuk menulis variabel yang sempurna dari potongan kode bash yang sempurna. Mempelajari bagaimana melakukan hal -hal ini dengan benar sejak awal akan sangat membatasi jumlah kemungkinan bug yang dapat diperkenalkan secara tidak sengaja.

Nikmati, dan ganda kutipan variabel -variabel tersebut! 🙂

Tutorial Linux Terkait:

  • Daftar Alat Linux Kali Terbaik untuk Pengujian Penetrasi dan ..
  • Menangani input pengguna dalam skrip bash
  • Loop bersarang dalam skrip bash
  • Pengantar Otomatisasi Linux, Alat dan Teknik
  • Lanjutan regex bash canggih dengan contoh
  • Tutorial debugging GDB untuk pemula
  • Menguasai loop skrip bash
  • Variabel bash khusus dengan contoh
  • Ekspresi reguler Python dengan contoh
  • Cara menggunakan subshells bash di dalamnya jika pernyataan