Apakah itu termasuk jika variabel IS SET ke nilai ""?
Brent
11
Ya itu ... "-z" menguji string dengan panjang nol.
David Z
91
if [ ! -z "$VAR" ];
Aaron Copley
263
kebalikannya -zadalah-nif [ -n "$VAR" ];
Felipe Alvarez
19
Kutipan ganda memastikan bahwa variabel tidak terpecah. Sederhana $varpada baris perintah akan dibagi dengan spasi putih menjadi daftar parameter, sementara "$var"akan selalu menjadi hanya satu parameter. Mengutip variabel sering kali merupakan praktik yang baik dan menghentikan Anda dari tersandung pada nama file yang mengandung spasi putih (antara lain). Contoh: setelah melakukan a="x --help", coba cat $a- ini akan memberi Anda halaman bantuan cat. Kemudian coba cat "$a"- itu akan (biasanya) mengatakan cat: x --help: No such file or directory. Singkatnya, kutip lebih awal dan sering kutip dan Anda hampir tidak akan pernah menyesalinya.
Score_Under
247
Di Bash, ketika Anda tidak peduli dengan portabilitas ke shell yang tidak mendukungnya, Anda harus selalu menggunakan sintaks braket ganda:
Di Bash, menggunakan tanda kurung ganda, tanda kutip tidak diperlukan. Anda dapat menyederhanakan tes untuk variabel yang tidak mengandung nilai ke:
if[[ $variable ]]
Sintaks ini kompatibel dengan ksh (setidaknya ksh93, pokoknya). Ini tidak bekerja di POSIX murni atau kulit Bourne yang lebih tua seperti sh atau dash.
Itu if [[ $variable ]]bekerja dengan baik untuk saya, dan bahkan tidak membutuhkan set -uyang diminta oleh salah satu solusi yang diusulkan lainnya.
Teemu Leisti
3
Saya pikir ini lebih baik daripada jawaban yang diterima.
qed
2
Mengapa Anda merekomendasikan fitur non-portabel saat melakukannya tidak memberikan manfaat?
Alastair Irvine
19
@AlastairIrvine: Saya menyebutkan portabilitas dalam kalimat pertama dari jawaban saya, judul pertanyaan dan isi berisi kata "Bash" dan pertanyaan tersebut ditandai bash , dan struktur braket ganda memberikan keuntungan yang jelas dalam banyak hal. Dan saya tidak merekomendasikan mencampur gaya braket untuk alasan konsistensi dan perawatan. Jika Anda membutuhkan portabilitas penyebut umum maksimum dan terendah, gunakan shsebagai pengganti Bash. Jika Anda membutuhkan peningkatan kemampuan yang disediakannya, gunakan Bash dan gunakan sepenuhnya.
Dennis Williamson
2
@BrunoBronosky: Saya mengembalikan hasil edit. Tidak ada persyaratan untuk ;pada akhirnya. The thendapat berada di baris berikutnya tanpa titik koma sama sekali.
Dennis Williamson
230
Variabel dalam bash (dan semua shell yang kompatibel dengan POSIX) dapat berupa salah satu dari tiga status:
tidak disetel
atur ke string kosong
setel ke string yang tidak kosong
Sebagian besar waktu Anda hanya perlu tahu apakah suatu variabel diatur ke string yang tidak kosong, tetapi kadang-kadang penting untuk membedakan antara tidak disetel dan ditetapkan ke string kosong.
Berikut ini adalah contoh bagaimana Anda dapat menguji berbagai kemungkinan, dan ia bekerja dalam bash atau shell yang kompatibel dengan POSIX:
if[-z "${VAR}"];then
echo "VAR is unset or set to the empty string"fiif[-z "${VAR+set}"];then
echo "VAR is unset"fiif[-z "${VAR-unset}"];then
echo "VAR is set to the empty string"fiif[-n "${VAR}"];then
echo "VAR is set to a non-empty string"fiif[-n "${VAR+set}"];then
echo "VAR is set, possibly to the empty string"fiif[-n "${VAR-unset}"];then
echo "VAR is either unset or set to a non-empty string"fi
Ini adalah hal yang sama tetapi dalam bentuk tabel praktis:
The ${VAR+foo}membangun memperluas ke string kosong jika VARtidak disetel atau foojika VARdiatur untuk apa pun (termasuk string kosong).
The ${VAR-foo}membangun memperluas untuk nilai VARjika diatur (termasuk set ke string kosong) dan foojika diset. Ini berguna untuk menyediakan default yang dapat ditimpa pengguna (misalnya, ${COLOR-red}mengatakan untuk menggunakan redkecuali variabel COLORtelah disetel ke sesuatu).
Alasan mengapa [ x"${VAR}" = x ]sering direkomendasikan untuk menguji apakah suatu variabel tidak disetel atau disetel ke string kosong adalah karena beberapa implementasi dari [perintah (juga dikenal sebagai test) buggy. Jika VARdiatur ke sesuatu seperti -n, maka beberapa implementasi akan melakukan hal yang salah ketika diberikan [ "${VAR}" = "" ]karena argumen pertama ke [salah ditafsirkan sebagai -noperator, bukan string.
Pengujian untuk set variabel ke string kosong juga dapat dilakukan dengan menggunakan [ -z "${VAR-set}" ].
nwellnhof
@nwellnhof: Terima kasih! Saya memperbarui jawaban saya untuk menggunakan sintaks yang lebih singkat.
Richard Hansen
Apa perbedaan antara konstruk pertama dan terakhir? Keduanya berhubungan dengan "VAR tidak disetel atau disetel ke string yang tidak kosong".
Faheem Mitha
1
@FaheemMitha: Itu bukan salahmu - jawabanku sulit dibaca. Saya menambahkan tabel agar mudah-mudahan membuat jawaban lebih jelas.
Richard Hansen
2
Pemeriksaan yang tidak disetel tidak dapat diandalkan. Jika pengguna memanggil set -uatau set -o nounsetdalam bash, maka pengujian hanya akan menghasilkan kesalahan "bash: VAR: unbound variable". Lihat stackoverflow.com/a/13864829 untuk pemeriksaan unset yang lebih andal. Pergi ke saya untuk memeriksa apakah suatu variabel adalah nol atau tidak disetel [ -z "${VAR:-}" ]. Cek saya apakah suatu variabel tidak kosong adalah [ "${VAR:-}" ].
Kevin Jin
38
-z adalah cara terbaik.
Opsi lain yang saya gunakan adalah untuk menetapkan variabel, tetapi dapat ditimpa oleh variabel lain misalnya
export PORT=${MY_PORT:-5432}
Jika $MY_PORTvariabel kosong, maka PORTakan ditetapkan ke 5432, jika PORT diatur ke nilai MY_PORT. Perhatikan sintaksinya termasuk titik dua dan tanda hubung.
Alternatif yang saya [ -z "$foo" ]perhatikan adalah sebagai berikut, namun saya tidak yakin mengapa orang menggunakan metode ini, ada yang tahu?
["x${foo}"="x"]
Bagaimanapun juga jika Anda melarang variabel yang tidak disetel (baik oleh set -uatau set -o nounset), maka Anda akan mengalami masalah dengan kedua metode tersebut. Ada perbaikan sederhana untuk ini:
Ada komentar tentang alternatif -zdi pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Pada dasarnya, ini tidak dimaksudkan sebagai alternatif -z. Sebaliknya, ia menangani kasus-kasus di mana $foodapat berkembang menjadi sesuatu yang dimulai dengan metacharacter yang [atau testakan membingungkan. Menempatkan non-metacharacter sewenang-wenang di awal menghilangkan kemungkinan itu.
James Sneeringer
6
The Pertanyaan meminta bagaimana untuk memeriksa apakah suatu variabel string kosong dan jawaban terbaik sudah diberikan untuk itu.
Tapi saya mendarat di sini setelah beberapa waktu berlalu pemrograman dalam php dan apa yang sebenarnya saya cari adalah cek seperti fungsi kosong di php bekerja di bash shell.
Setelah membaca jawaban saya menyadari saya tidak berpikir dengan benar di bash, tapi bagaimanapun pada saat itu fungsi seperti kosong di php akan sangat berguna dalam kode bash saya.
Karena saya pikir ini bisa terjadi pada orang lain, saya memutuskan untuk mengubah fungsi kosong php di bash
Menurut manual php : variabel dianggap kosong jika tidak ada atau nilainya salah satu dari yang berikut:
"" (string kosong)
0 (0 sebagai bilangan bulat)
0,0 (0 sebagai pelampung)
"0" (0 sebagai string)
sebuah array kosong
variabel dideklarasikan, tetapi tanpa nilai
Tentu saja kasus null dan false tidak dapat dikonversi dalam bash, sehingga dihilangkan.
function empty
{local var="$1"# Return true if:# 1. var is a null string ("" as empty string)# 2. a non set variable is passed# 3. a declared variable or array but without a value is passed# 4. an empty array is passedif test -z "$var"then[[ $( echo "1")]]return# Return true if var is zero (0 as an integer or "0" as a string)elif["$var"==02>/dev/null ]then[[ $( echo "1")]]return# Return true if var is 0.0 (0 as a float)elif["$var"==0.02>/dev/null ]then[[ $( echo "1")]]returnfi[[ $( echo "")]]}
Contoh penggunaan:
if empty "${var}"then
echo "empty"else
echo "not empty"fi
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
Setelah mengatakan bahwa dalam logika bash, cek pada nol pada fungsi ini dapat menyebabkan masalah samping, siapa pun yang menggunakan fungsi ini harus mengevaluasi risiko ini dan mungkin memutuskan untuk memotong cek tersebut sehingga hanya menyisakan yang pertama.
Juga akan gagal di beberapa shell jika foo dimulai dengan tanda hubung karena ditafsirkan sebagai opsi. Misalnya pada solaris ksh , zsh dan bash tidak ada masalah, sh dan / bin / test akan gagal
Beberapa shell tidak menerima tanda sama dengan dobel.
Dennis Williamson
1
Pertanyaannya adalah tentang bash. Saya menggunakan bash. Bekerja dengan baik untuk saya. Apa yang sebenarnya Anda bicarakan?
Fedir RYKHTIK
2
Jika Anda menggunakan Bash, Anda harus menggunakan tanda kurung ganda. Komentar saya sebelumnya adalah pernyataan fakta sederhana bagi mereka yang mungkin membaca jawaban Anda dan menggunakan shell yang berbeda.
5 sen saya: ada juga sintaks yang lebih pendek daripada if ..., yang ini:
VALUE="${1?"Usage: $0 value"}"
Baris ini akan menetapkan VALUE jika argumen telah disediakan dan akan mencetak pesan kesalahan yang diawali dengan nomor baris skrip jika terjadi kesalahan (dan akan menghentikan eksekusi skrip).
Contoh lain dapat ditemukan dalam panduan abs (cari «Contoh 10-7»).
Bukan jawaban yang pasti, tetapi mengalami trik ini. Jika string yang Anda cari berasal dari "sebuah perintah" maka Anda sebenarnya dapat menyimpan perintah itu dalam env. variabel dan kemudian jalankan setiap kali untuk pernyataan if, maka tidak diperlukan tanda kurung!
Misalnya perintah ini, yang menentukan apakah Anda menggunakan debian:
Jadi ini seperti cara tidak langsung (jalankan ulang setiap kali) untuk memeriksa string kosong (kebetulan memeriksa respons kesalahan dari perintah, tetapi juga mengembalikan string kosong).
Jawaban:
Ini akan mengembalikan true jika variabel tidak disetel atau disetel ke string kosong ("").
sumber
if [ ! -z "$VAR" ];
-z
adalah-n
if [ -n "$VAR" ];
$var
pada baris perintah akan dibagi dengan spasi putih menjadi daftar parameter, sementara"$var"
akan selalu menjadi hanya satu parameter. Mengutip variabel sering kali merupakan praktik yang baik dan menghentikan Anda dari tersandung pada nama file yang mengandung spasi putih (antara lain). Contoh: setelah melakukana="x --help"
, cobacat $a
- ini akan memberi Anda halaman bantuancat
. Kemudian cobacat "$a"
- itu akan (biasanya) mengatakancat: x --help: No such file or directory
. Singkatnya, kutip lebih awal dan sering kutip dan Anda hampir tidak akan pernah menyesalinya.Di Bash, ketika Anda tidak peduli dengan portabilitas ke shell yang tidak mendukungnya, Anda harus selalu menggunakan sintaks braket ganda:
Salah satu dari yang berikut:
Di Bash, menggunakan tanda kurung ganda, tanda kutip tidak diperlukan. Anda dapat menyederhanakan tes untuk variabel yang tidak mengandung nilai ke:
Sintaks ini kompatibel dengan ksh (setidaknya ksh93, pokoknya). Ini tidak bekerja di POSIX murni atau kulit Bourne yang lebih tua seperti sh atau dash.
Lihat jawaban saya di sini dan BashFAQ / 031 untuk informasi lebih lanjut tentang perbedaan antara tanda kurung ganda dan tunggal.
Anda dapat menguji untuk melihat apakah suatu variabel secara khusus tidak disetel (berbeda dari string kosong):
di mana "x" adalah arbitrer.
Jika Anda ingin tahu apakah suatu variabel adalah nol tetapi tidak disetel:
sumber
if [[ $variable ]]
bekerja dengan baik untuk saya, dan bahkan tidak membutuhkanset -u
yang diminta oleh salah satu solusi yang diusulkan lainnya.sh
sebagai pengganti Bash. Jika Anda membutuhkan peningkatan kemampuan yang disediakannya, gunakan Bash dan gunakan sepenuhnya.;
pada akhirnya. Thethen
dapat berada di baris berikutnya tanpa titik koma sama sekali.Variabel dalam bash (dan semua shell yang kompatibel dengan POSIX) dapat berupa salah satu dari tiga status:
Sebagian besar waktu Anda hanya perlu tahu apakah suatu variabel diatur ke string yang tidak kosong, tetapi kadang-kadang penting untuk membedakan antara tidak disetel dan ditetapkan ke string kosong.
Berikut ini adalah contoh bagaimana Anda dapat menguji berbagai kemungkinan, dan ia bekerja dalam bash atau shell yang kompatibel dengan POSIX:
Ini adalah hal yang sama tetapi dalam bentuk tabel praktis:
The
${VAR+foo}
membangun memperluas ke string kosong jikaVAR
tidak disetel ataufoo
jikaVAR
diatur untuk apa pun (termasuk string kosong).The
${VAR-foo}
membangun memperluas untuk nilaiVAR
jika diatur (termasuk set ke string kosong) danfoo
jika diset. Ini berguna untuk menyediakan default yang dapat ditimpa pengguna (misalnya,${COLOR-red}
mengatakan untuk menggunakanred
kecuali variabelCOLOR
telah disetel ke sesuatu).Alasan mengapa
[ x"${VAR}" = x ]
sering direkomendasikan untuk menguji apakah suatu variabel tidak disetel atau disetel ke string kosong adalah karena beberapa implementasi dari[
perintah (juga dikenal sebagaitest
) buggy. JikaVAR
diatur ke sesuatu seperti-n
, maka beberapa implementasi akan melakukan hal yang salah ketika diberikan[ "${VAR}" = "" ]
karena argumen pertama ke[
salah ditafsirkan sebagai-n
operator, bukan string.sumber
[ -z "${VAR-set}" ]
.set -u
atauset -o nounset
dalam bash, maka pengujian hanya akan menghasilkan kesalahan "bash: VAR: unbound variable". Lihat stackoverflow.com/a/13864829 untuk pemeriksaan unset yang lebih andal. Pergi ke saya untuk memeriksa apakah suatu variabel adalah nol atau tidak disetel[ -z "${VAR:-}" ]
. Cek saya apakah suatu variabel tidak kosong adalah[ "${VAR:-}" ]
.-z
adalah cara terbaik.Opsi lain yang saya gunakan adalah untuk menetapkan variabel, tetapi dapat ditimpa oleh variabel lain misalnya
Jika
$MY_PORT
variabel kosong, makaPORT
akan ditetapkan ke 5432, jika PORT diatur ke nilaiMY_PORT
. Perhatikan sintaksinya termasuk titik dua dan tanda hubung.sumber
set -o nounset
dalam beberapa skrip.Jika Anda tertarik membedakan kasus status set-kosong versus tidak disetel, lihat opsi -u untuk bash:
sumber
Alternatif yang saya
[ -z "$foo" ]
perhatikan adalah sebagai berikut, namun saya tidak yakin mengapa orang menggunakan metode ini, ada yang tahu?Bagaimanapun juga jika Anda melarang variabel yang tidak disetel (baik oleh
set -u
atauset -o nounset
), maka Anda akan mengalami masalah dengan kedua metode tersebut. Ada perbaikan sederhana untuk ini:Catatan: ini akan membuat variabel Anda undef.
sumber
-z
di pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . Pada dasarnya, ini tidak dimaksudkan sebagai alternatif-z
. Sebaliknya, ia menangani kasus-kasus di mana$foo
dapat berkembang menjadi sesuatu yang dimulai dengan metacharacter yang[
atautest
akan membingungkan. Menempatkan non-metacharacter sewenang-wenang di awal menghilangkan kemungkinan itu.The Pertanyaan meminta bagaimana untuk memeriksa apakah suatu variabel string kosong dan jawaban terbaik sudah diberikan untuk itu.
Tapi saya mendarat di sini setelah beberapa waktu berlalu pemrograman dalam php dan apa yang sebenarnya saya cari adalah cek seperti fungsi kosong di php bekerja di bash shell.
Setelah membaca jawaban saya menyadari saya tidak berpikir dengan benar di bash, tapi bagaimanapun pada saat itu fungsi seperti kosong di php akan sangat berguna dalam kode bash saya.
Karena saya pikir ini bisa terjadi pada orang lain, saya memutuskan untuk mengubah fungsi kosong php di bash
Menurut manual php :
variabel dianggap kosong jika tidak ada atau nilainya salah satu dari yang berikut:
Tentu saja kasus null dan false tidak dapat dikonversi dalam bash, sehingga dihilangkan.
Contoh penggunaan:
Demo:
cuplikan berikut:
output:
Setelah mengatakan bahwa dalam logika bash, cek pada nol pada fungsi ini dapat menyebabkan masalah samping, siapa pun yang menggunakan fungsi ini harus mengevaluasi risiko ini dan mungkin memutuskan untuk memotong cek tersebut sehingga hanya menyisakan yang pertama.
sumber
empty
- mengapa Anda menulis[[ $( echo "1" ) ]] ; return
bukan hanyareturn 1
?seluruh if-then dan -z tidak perlu.
sumber
Ini benar ketika $ FOO disetel dan kosongkan:
sumber
Secara pribadi lebih suka cara yang lebih jelas untuk memeriksa:
sumber
ekstensi oneliner dari solusi duffbeer703 :
sumber
5 sen saya: ada juga sintaks yang lebih pendek daripada
if ...
, yang ini:Baris ini akan menetapkan VALUE jika argumen telah disediakan dan akan mencetak pesan kesalahan yang diawali dengan nomor baris skrip jika terjadi kesalahan (dan akan menghentikan eksekusi skrip).
Contoh lain dapat ditemukan dalam panduan abs (cari «Contoh 10-7»).
sumber
Bukan jawaban yang pasti, tetapi mengalami trik ini. Jika string yang Anda cari berasal dari "sebuah perintah" maka Anda sebenarnya dapat menyimpan perintah itu dalam env. variabel dan kemudian jalankan setiap kali untuk pernyataan if, maka tidak diperlukan tanda kurung!
Misalnya perintah ini, yang menentukan apakah Anda menggunakan debian:
grep debian /proc/version
contoh lengkap:
Jadi ini seperti cara tidak langsung (jalankan ulang setiap kali) untuk memeriksa string kosong (kebetulan memeriksa respons kesalahan dari perintah, tetapi juga mengembalikan string kosong).
sumber