Kode berikut keluar dengan kesalahan variabel tak terikat. Bagaimana cara memperbaikinya, saat masih menggunakan set -oopsi kata benda?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
Kode berikut keluar dengan kesalahan variabel tak terikat. Bagaimana cara memperbaikinya, saat masih menggunakan set -oopsi kata benda?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
Jawaban:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
Dalam kasus ini, VALUEberakhir menjadi string kosong jika WHATEVERtidak disetel. Kami menggunakan {parameter:-word}perluasan, yang dapat Anda cari di man bashbawah "Perluasan Parameter".
:-memeriksa apakah variabel tidak disetel atau kosong. Jika Anda ingin memeriksa hanya apakah itu tidak diset, gunakan -: VALUE=${WHATEVER-}. Juga, cara yang lebih mudah dibaca untuk memeriksa apakah suatu variabel kosong:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVERhanya berisi spasi - Lihat jawaban saya.
! -z" daripada hanya " -n"?
Anda perlu mengutip variabel jika ingin mendapatkan hasil yang diharapkan:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Uji:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
"info bash", "${WHATEVER-}"harus memiliki ":"(kolon) sebelum "-"(dash) seperti: "${WHATEVER:-}", dan "${WHATEVER+defined}"harus memiliki usus sebelum "+"(plus) seperti: "${WHATEVER:+defined}". Bagi saya, itu bekerja dengan cara apa pun, dengan atau tanpa titik dua. Pada beberapa versi 'nix, ini mungkin tidak akan berfungsi tanpa menyertakan titik dua, jadi mungkin harus ditambahkan.
-, +, :+, dan :-semua didukung. Yang pertama mendeteksi apakah variabel disetel , dan yang terakhir mendeteksi apakah itu disetel atau kosong . Dari man bash: "Menghilangkan titik dua menghasilkan pengujian hanya untuk parameter yang tidak disetel."
Bagaimana dengan oneliner?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z memeriksa variabel kosong atau tidak disetel
-zhanya memeriksa apakah parameter berikutnya kosong. -zhanyalah argumen dari [perintah. Ekspansi variabel terjadi sebelum [ -zdapat melakukan apapun.
Asumsi:
$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
Jika Anda ingin skrip non-interaktif mencetak kesalahan dan keluar jika variabel null atau tidak disetel:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
Jika Anda tidak ingin skrip keluar:
$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
Anda bahkan dapat menggunakan [dan ]sebagai pengganti [[dan yang ]]lebih baru, tetapi yang terakhir lebih disukai di Bash.
Perhatikan apa yang dilakukan titik dua di atas. Dari dokumen :
Dengan kata lain, jika titik dua disertakan, operator menguji keberadaan kedua parameter dan nilainya bukan null; jika titik dua dihilangkan, operator hanya menguji keberadaannya.
Tampaknya tidak perlu -natau -z.
Singkatnya, saya biasanya hanya menggunakan [[ "${VAR:?}" ]]. Per contoh, ini mencetak kesalahan dan keluar jika variabel null atau tidak disetel.
Kamu bisa memakai
if [[ ${WHATEVER:+$WHATEVER} ]]; then
tapi
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
mungkin lebih mudah dibaca.
=operator standar (POSIX) , bukan ==untuk membantu portabilitas, dan [sebaliknya [[jika memungkinkan.
set -o nounsetyang khusus untuk pesta. Jika Anda meletakkan a #!/bin/bashdi bagian atas skrip Anda, sebenarnya yang terbaik adalah menggunakan penyempurnaan bash.
Meskipun ini tidak persis kasus penggunaan meminta di atas, saya telah menemukan bahwa jika Anda ingin menggunakan nounset(atau-u ) perilaku default adalah salah satu yang ingin: untuk keluar nol dengan pesan deskriptif.
Butuh waktu cukup lama bagi saya untuk menyadari hal ini sehingga saya pikir itu layak untuk diposting sebagai solusi.
Jika yang Anda inginkan hanyalah menggemakan hal lain saat keluar, atau melakukan pembersihan, Anda dapat menggunakan jebakan.
The :-operator adalah mungkin apa yang Anda inginkan sebaliknya.