Menguji apakah suatu variabel kosong dalam skrip shell

27

Saya telah melihat teknik berikut ini digunakan berkali-kali pada banyak shell yang berbeda, untuk menguji apakah suatu variabel kosong:

if [ "x$1" = "x" ]; then 
    # Variable is empty
fi

Apakah ada keuntungan menggunakan ini lebih kanonik if [ -z "$1" ]? Mungkinkah itu masalah portabilitas?

rahmu
sumber

Jawaban:

17

Beberapa shell historis menerapkan parser yang sangat sederhana yang dapat dikacaukan oleh hal-hal seperti di [ -n = "" ]mana operan pertama =terlihat seperti operator, dan akan menguraikannya sebagai [ -n = ]atau menyebabkan kesalahan sintaksis. Dalam [ "x$1" = x"" ], xawalan memastikan bahwa x"$1"tidak mungkin terlihat seperti operator, dan satu-satunya cara shell dapat menguraikan tes ini adalah dengan memperlakukan =sebagai operator biner.

Semua shell modern, dan bahkan sebagian besar shell yang lebih lama masih beroperasi, ikuti aturan POSIX yang mengamanatkan bahwa semua ekspresi uji hingga 4 kata diurai dengan benar. Jadi [ -z "$1" ]adalah cara yang tepat untuk menguji jika $1kosong , dan [ "$x" = "$y" ]merupakan cara yang tepat untuk menguji kesetaraan dua variabel.

Bahkan beberapa shell saat ini dapat dikacaukan dengan ekspresi yang lebih lama, dan beberapa ekspresi sebenarnya ambigu, jadi hindari penggunaan -adan -ooperator untuk membangun tes boolean yang lebih lama, dan alih-alih gunakan panggilan terpisah ke [dan shell milik sendiri &&dan ||operator boolean.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
3
Bukan hanya kerang sejarah . Beberapa ksh88 berdasarkan shpada beberapa Unix komersial masih memiliki masalah. Lihat di sini untuk detailnya.
Stéphane Chazelas
Pernyataan ini salah: [ -z "$1" ]adalah cara pengujian yang benar jika $1kosong . sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'- keduanya mengembalikan 0, tetapi dalam kasus kedua $1tidak boleh kosong karena tidak ada.
mikeserv
3

Tes di atas juga akan menyebabkan kesalahan jika Anda menjalankan dengan "set -u" atau "set -o nounset"

Cara yang lebih stabil untuk memeriksa variabel kosong adalah dengan menggunakan ekspansi parameter :

MYVAR = $ {MYVAR: - "Nilai Buruk"}

Metode ini berfungsi untuk shell bourne tradisional, juga ksh, dan bash.

Scott Hoffman
sumber
2
Saya yakin ini ditulis sebagai -> M = $ {M: - "Nilai Buruk"}
Gyan
0
    function isBlank {
 valueNoSpaces=$(echo "$@" | tr -d ' ')

 if [  "$valueNoSpaces" == null ] || [ -z "$valueNoSpaces" ] 
 then
       echo true ;
 else
       echo ""  ;
 fi
}

#Test
if [ $(isBlank "      ") ] 
then
    echo "isBlank \"      \" : it's blank"
else
    echo " isBlank \"      \": it is not blank"
fi

if [ $(isBlank "abc") ] 

then
    echo "isBlank \"abc\" : it's blank"
else
    echo "isBlank \"abc\" :it is not blank"
fi

if [ $(isBlank null) ] 
then
      echo "isBlank null : it's blank"
else
    echo "isBlank null : it is not blank"
fi

if [ $(isBlank "") ] 
then
    echo "isBlank \"\" : it's blank"
else
    echo "isBlank \"\" : it is not blank"
fi

#Result
isBlank "      " : it's blank

isBlank "abc" :it is not blank

isBlank null : it's blank

isBlank "" : it's blank
aslam mohammed
sumber
3
Hai! Saya tidak yakin bagaimana ini menjawab pertanyaan, yang menanyakan mengapa menggunakan =versus -z, sekarang bagaimana.
Dhag