Sunting: Ini adalah versi yang lebih lengkap yang menunjukkan lebih banyak perbedaan antara [
(alias test
) dan [[
.
Tabel berikut menunjukkan bahwa apakah suatu variabel dikutip atau tidak, apakah Anda menggunakan tanda kurung tunggal atau ganda dan apakah variabel hanya berisi spasi adalah hal-hal yang mempengaruhi apakah menggunakan tes dengan atau tanpa -n/-z
cocok untuk memeriksa variabel.
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
Jika Anda ingin tahu apakah suatu variabel panjangnya tidak nol, lakukan salah satu dari yang berikut:
- mengutip variabel dalam kurung tunggal (kolom 2a)
- gunakan
-n
dan kutip variabel dalam kurung tunggal (kolom 4a)
- gunakan tanda kurung ganda dengan atau tanpa mengutip dan dengan atau tanpa
-n
(kolom 1b - 4b)
Perhatikan pada kolom 1a mulai dari baris berlabel "dua" bahwa hasilnya menunjukkan bahwa [
mengevaluasi isi variabel seolah-olah mereka adalah bagian dari ekspresi kondisional (hasilnya cocok dengan pernyataan yang tersirat oleh "T" atau "F" di kolom keterangan). Ketika [[
digunakan (kolom 1b), konten variabel dilihat sebagai string dan tidak dievaluasi.
Kesalahan dalam kolom 3a dan 5a disebabkan oleh fakta bahwa nilai variabel termasuk spasi dan variabel tidak dikutip. Sekali lagi, seperti yang ditunjukkan pada kolom 3b dan 5b, [[
mengevaluasi konten variabel sebagai string.
Sejalan dengan itu, untuk pengujian untuk string panjang nol, kolom 6a, 5b dan 6b menunjukkan cara yang benar untuk melakukan itu. Perhatikan juga bahwa salah satu tes ini dapat dinegasikan jika meniadakan menunjukkan maksud yang lebih jelas daripada menggunakan operasi yang berlawanan. Sebagai contoh: if ! [[ -n $var ]]
.
Jika Anda menggunakan [
, kunci untuk memastikan bahwa Anda tidak mendapatkan hasil yang tidak diharapkan adalah mengutip variabel. Menggunakannya [[
, itu tidak masalah.
Pesan kesalahan, yang sedang ditekan, adalah "operator yang tidak diharapkan" atau "operator biner yang diharapkan".
Ini adalah skrip yang menghasilkan tabel di atas.
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF
["
vs[-n"
(pertanyaan pertama OP) menunjukkan bahwa mereka benar-benar setara, bukan?[["
Lebih baik menggunakan yang lebih kuat
[[
sejauh menyangkut Bash.Kasus biasa
Dua konstruksi di atas terlihat bersih dan mudah dibaca. Mereka harus cukup dalam banyak kasus.
Perhatikan bahwa kita tidak perlu mengutip ekspansi variabel di dalamnya
[[
karena tidak ada bahaya pemisahan kata dan penggumpalan .Untuk mencegah keluhan lembut dan shellcheck tentang , kita bisa menggunakan opsi.
[[ $var ]]
[[ ! $var ]]
-n
Kasing langka
Dalam kasus yang jarang kita harus membuat perbedaan antara "diset ke string kosong" vs "tidak disetel sama sekali", kita bisa menggunakan ini:
Kami juga dapat menggunakan
-v
tes:Posting dan dokumentasi terkait
Ada banyak posting yang berkaitan dengan topik ini. Berikut ini beberapa di antaranya:
[[
vs[
[
vs[[
sumber
Berikut ini beberapa tes lagi
Benar jika string tidak kosong:
Benar jika string kosong:
sumber
Jawaban yang benar adalah sebagai berikut:
Perhatikan penggunaan
[[...]]
, yang menangani dengan benar mengutip variabel untuk Anda.sumber
-n
saat tidak benar-benar dibutuhkan di Bash?Cara alternatif dan mungkin lebih transparan untuk mengevaluasi variabel lingkungan kosong adalah menggunakan ...
sumber
bash
adalah alat yang lebih tajam dari pendahulunya.[ "$ENV_VARIABLE" != "" ]
akan bekerja pada setiap shell dengantest
implementasi yang sesuai dengan POSIX - bukan hanya bash, tetapi ash / dash / ksh / etc.-a
atau-o
untuk menggabungkan tes tetapi sebaliknya gunakan[ ... ] && [ ... ]
atau[ ... ] || [ ... ]
dan satu-satunya kasus sudut yang dapat diterapkan untuk menggunakan data variabel arbitrer dalam suatu tes tertutup rapat.Gunakan
case/esac
untuk menguji:sumber
case
.case
bekerja paling baik ketika ada lebih dari dua alternatif.case
tidak dimaksudkan untuk penggunaan seperti ini.