bagaimana cara memeriksa apakah $ 1 dan $ 2 adalah nol?

40

Saya menjalankan beberapa skrip yang melewati argumen string dan saya ingin lakukan jika pernyataan lain ditampilkan di bawah ini:

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

tapi itu terlihat Error too many argument. Mengapa?

taymindis Woon
sumber
Anda harus menyediakan 1. perintah yang Anda panggil skrip dan 2. hasil lengkap.
Lucio
2
Anda harus menggunakan [[ ]]. Kalau tidak, Anda harus mengutip variabel Anda.
Christophe De Troyer
Jika $ 1 tidak ada maka $ 2 akan menjadi $ 1 yang membuat tes $ 1 dan $ 2 keduanya menjadi nol tampaknya tidak relevan.
WinEunuuchs2Unix
@ WinEunuuchs2Unix Tidak selalu tidak relevan - dalam beberapa kasus Anda ingin memastikan bahwa ada sesuatu yang sebenarnya bukan string kosong atau nol dalam argumen. $1bisa tidak disetel atau disetel ke string nol oleh pengguna skrip. Pertimbangkan urutan perintah ini: $ set '' barlalu echo "x${1}x";Kedua variabel ditetapkan, tetapi salah satunya adalah nol.
Sergiy Kolodyazhnyy

Jawaban:

55

Coba gunakan tes -z:

if [ -z "$1" ] && [ -z "$2" ]

Dari manusia bash:

-z string
   True if the length of string is zero.
Sylvain Pineau
sumber
Ini bekerja untuk saya!
pengisgood
Sangat menarik bahwa jawaban yang paling banyak dipilih dan diterima tidak benar - benar menjawab pertanyaan yang diajukan.
mehmet
Saat menulis skrip shell portabel, flag ini harus digunakan dengan hati-hati, karena pada iklan Unix tertentu flag ini rusak. Lihat jawaban saya untuk sumber tertaut.
Sergiy Kolodyazhnyy
14

Karena ini ditandai bash, saya sarankan Anda menggunakan konstruksi tes diperpanjang ( [[...]]) , dan lupakan tanda kutip:

if [[ -z $1 && -z $2 ]]; then
...

Kecuali jika Anda shmenginginkan kompatibilitas / POSIX, tidak ada alasan untuk tidak menggunakannya [[ ]].

muru
sumber
3

Berikut ini juga berfungsi,

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi
Avinash Raj
sumber
The &&dan pemisah perintah logis lainnya tidak diperbolehkan dalam klasik test. Anda harus menggunakan konstruksi tes lain sebagai gantinya (seperti -a, saya pikir)
muru
3

Untuk versi jawaban yang lama, lihat bagian kedua dari jawaban ini. Jika Anda ingin tahu detailnya, baca terus

Penyebab masalah

Dalam pertanyaan itu sendiri, dilaporkan bahwa OP melihat too many arguments error, yang ketika diuji bashtampaknya tidak menjadi masalah:

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

Dengan /bin/shyang sebenarnya terhubung ke /bin/dashUbuntu, kesalahan dilaporkan sebagai berikut:

$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator

Dan /bin/testjuga standalone :

$ /usr/bin/test $1 != ''  
/usr/bin/test: missing argument after ‘’

Sidenote: Jika Anda bertanya-tanya apa /usr/bin/testdan mengapa saya menggunakan bashdan sh, maka Anda harus tahu itu [adalah alias untuk testperintah, yang juga ada sebagai mandiri yang dapat dieksekusi atau lebih umum - sebagai built-in shell yang merupakan masing-masing shell yang akan digunakan terlebih dahulu . Adapun ifpernyataan, mereka beroperasi pada patung keluar dari perintah, karenanya mengapa [dan testperintah, dengan segala sesuatu yang lain argumen untuk perintah itu - urutan yang tidak tepat dari argumen baris perintah menyebabkan kesalahan.

Kembali ke topik: tidak jelas bagaimana OP mendapat kesalahan yang tidak terkait. Namun, dalam ketiga kasus ini masalahnya sama - variabel yang tidak disetel akan diperlakukan sebagai kosong, jadi apa yang shell lihat dengan variabel-variabel yang tidak dikutip ini adalah

[ != '' ]

yang memecah sintaks yang testmengerti. Ingat apa yang saya katakan tentang urutan argumen baris perintah yang tidak tepat? Karena itu mengapa mengutip itu penting. Mari kita aktifkan hasil diagnostik dan lihat apa yang dijalankan shell:

$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ] 
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars

Cara yang lebih baik untuk menguji variabel yang tidak disetel

Pendekatan yang sangat sering Anda lihat adalah:

 if [ "x$var1" == "x"  ] && [ "x$var2" == "x"  ];                                                                
 then
     echo "both variables are null"
 fi

Mengutip Gilles :

Dalam ["x $ 1" = "x"], awalan x memastikan bahwa x "$ 1" tidak mungkin terlihat seperti operator, sehingga satu-satunya cara shell dapat menguraikan tes ini adalah dengan memperlakukan = sebagai operator biner.

Agaknya, ini harus cukup portabel karena saya sudah melihatnya di /bin/shskrip. Ini juga dapat digabungkan seperti pada

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

Tentu saja kita dapat menggunakan -zbendera, namun menurut penelitian di beberapa kerang, terutama ksh88 (menurut Stephane Chazelas ), bendera ini salah.

Lihat juga

Sergiy Kolodyazhnyy
sumber
+1 untuk pendekatan yang sangat menarik.
WinEunuuchs2Unix
@ WinEunuuchs2Unix Diedit untuk membuatnya lebih menarik :)
Sergiy Kolodyazhnyy
1

Saya pikir judul posting tidak akurat, karena maksud dalam pesan itu adalah untuk memeriksa apakah $ 1 dan $ 2 bukan nol. Contoh yang diberikan hanya menghilangkan tanda kutip ganda dalam $ 1 dan $ 2 untuk bekerja. Variabel harus dikutip ganda agar diperluas ketika membandingkan string. Tetapi, untuk memeriksa apakah $ 1 dan $ 2 ada sama dengan memeriksa apakah $ 2 ada, karena tidak bisa ada jika $ 1 tidak ada. Perintah 'jika' juga tidak diperlukan dalam kasus ini, karena 'tes' mengembalikan benar / salah dan menggunakan '&&' sebagai 'maka' jika pengembalian adalah 0 / benar:

[ "$2" != '' ] && commands...

Lebih sederhana, dengan -n (bukan nol):

[ -n "$2" ] && commands...

Untuk "memeriksa apakah $ 1 dan $ 2 adalah nol" akan sama dengan memeriksa jika tidak ada parameter:

[ $# -eq 0 ] && commands...
Guariba Som
sumber