Pertanyaan Bagaimana cara menentukan apakah variabel bash kosong?


Apa cara terbaik untuk menentukan apakah variabel dalam bash kosong ("")?

Saya telah mendengar bahwa saya disarankan untuk melakukannya if [ "x$variable" = "x" ]

Apakah itu benar cara? (Pasti ada sesuatu yang lebih lugas)


719
2018-05-12 17:54






Jawaban:


Ini akan mengembalikan true jika variabel tidak disetel atau disetel ke string kosong ("").

if [ -z "$VAR" ];

980
2018-05-12 18:06



Apakah itu termasuk jika variabel IS SET dengan nilai ""? - Brent
Ya itu ... "-z" tes untuk string nol-panjang. - David Z
if [ ! -z "$VAR" ]; - Aaron Copley
kebalikan dari -z aku s -n  if [ -n "$VAR" ]; - Felipe Alvarez
Tanda kutip ganda memastikan bahwa variabel tidak terpecah. Sederhana $var pada baris perintah akan dipisah oleh spasinya ke dalam daftar parameter, sementara "$var" hanya akan menjadi satu parameter. Mengutip variabel sering merupakan praktik yang baik dan menghentikan Anda dari tersandung pada nama file yang mengandung spasi (antara lain). Contoh: setelah melakukan a="x --help", coba cat $a - Ini akan memberi Anda halaman bantuan untuk cat. Maka cobalah cat "$a" - Itu (biasanya) katakan cat: x --help: No such file or directory. Singkatnya, kutipan awal dan kutipan sering dan Anda hampir tidak akan pernah menyesalinya. - Score_Under


Di Bash, ketika Anda tidak peduli dengan portabilitas ke shell yang tidak mendukungnya, Anda harus selalu menggunakan sintaks double-bracket:

Salah satu dari yang berikut:

if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]

Di Bash, menggunakan tanda kurung ganda, tanda kutipnya tidak diperlukan. Anda dapat menyederhanakan tes untuk variabel itu tidak mengandung nilai untuk:

if [[ $variable ]]

Sintaks ini kompatibel dengan ksh (setidaknya ksh93, anyway). Ini tidak bekerja di POSIX murni atau Bourne shell yang lebih tua seperti sh atau dash.

Lihat jawabanku di sini dan BashFAQ / 031 untuk informasi lebih lanjut tentang perbedaan antara kurung ganda dan tunggal.

Anda dapat menguji untuk melihat apakah suatu variabel secara khusus tidak disetel (sebagai berbeda dari string kosong):

if [[ -z ${variable+x} ]]

di mana "x" adalah sewenang-wenang.

Jika Anda ingin mengetahui apakah suatu variabel nol tetapi tidak disetel:

if [[ -z $variable && ${variable+x} ]]

227
2018-02-25 03:37



Bahwa if [[ $variable ]] bekerja dengan baik untuk saya, dan bahkan tidak membutuhkan set -u yang dibutuhkan oleh salah satu solusi lain yang diusulkan. - Teemu Leisti
Saya pikir ini lebih baik daripada jawaban yang diterima. - qed
Mengapa Anda menyarankan fitur non-portabel ketika melakukan hal itu tidak bermanfaat? - Alastair Irvine
@AlastairIrvine: Saya menyebutkan portabilitas dalam kalimat pertama dari jawaban saya, judul pertanyaan dan isi berisi kata "Bash" dan pertanyaannya ditandai pesta, dan struktur braket ganda menyediakan keuntungan yang jelas dalam banyak hal. Dan saya tidak menyarankan mencampur gaya bracket untuk alasan konsistensi dan pemeliharaan. Jika Anda membutuhkan maksimum, portabilitas denominator umum terendah, gunakan sh bukannya Bash. Jika Anda membutuhkan peningkatan kemampuan yang disediakan, gunakan Bash dan gunakan sepenuhnya. - Dennis Williamson
@BrunoBronosky: Saya mengembalikan hasil edit. Tidak ada persyaratan untuk itu ; pada akhirnya. Itu then dapat berada di baris berikutnya tanpa titik koma sama sekali. - Dennis Williamson


Variabel dalam bash (dan shell yang kompatibel dengan POSIX) dapat berada di salah satu dari tiga status:

  • tidak disetel
  • diatur ke string kosong
  • diatur ke string yang tidak kosong

Sebagian besar waktu Anda hanya perlu mengetahui apakah suatu variabel disetel ke string yang tidak kosong, tetapi terkadang penting untuk membedakan antara tidak disetel dan disetel ke string kosong.

Berikut ini adalah contoh bagaimana Anda dapat menguji berbagai kemungkinan, dan bekerja di bash atau shell yang kompatibel dengan POSIX:

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
    echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -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 yang berguna:

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

Itu ${VAR+foo} konstruk mengembang ke string kosong jika VAR tidak disetel atau tidak foo jika VAR diatur ke apa pun (termasuk string kosong).

Itu ${VAR-foo} membangun memperluas ke nilai VAR jika disetel (termasuk disetel ke string kosong) dan foo jika tidak disetel. Ini berguna untuk menyediakan default yang dapat diganti pengguna (mis., ${COLOR-red} mengatakan untuk digunakan red kecuali variabelnya COLOR telah diatur untuk sesuatu).

Alasan mengapa [ x"${VAR}" = x ] sering direkomendasikan untuk menguji apakah suatu variabel tidak disetel atau disetel ke string kosong karena beberapa implementasi dari [ perintah (juga dikenal sebagai test) adalah buggy. Jika VAR diatur ke sesuatu seperti -n, maka beberapa implementasi akan melakukan hal yang salah saat diberikan [ "${VAR}" = "" ] karena argumen pertama [ secara keliru ditafsirkan sebagai -n operator, bukan string.


205
2018-04-24 20:39



Pengujian untuk variabel yang disetel ke string kosong juga bisa dilakukan menggunakan [ -z "${VAR-set}" ]. - nwellnhof
@nwellnhof: Terima kasih! Saya memperbarui jawaban saya untuk menggunakan sintaks briefer. - Richard Hansen
@FaheemMitha: Bukan salah Anda - jawaban saya sulit dibaca. Saya menambahkan meja untuk semoga membuat jawabannya lebih jelas. - Richard Hansen
@RichardHansen: Terima kasih, itu adalah tambahan yang bermanfaat. - Faheem Mitha
Pemeriksaan yang tidak disetel tidak dapat diandalkan. Jika pengguna menelepon set -u atau set -o nounset di bash, maka tes hanya akan menghasilkan kesalahan "bash: VAR: variabel terikat". Lihat stackoverflow.com/a/13864829 untuk pemeriksaan tidak disetel yang lebih andal. Go-to saya untuk memeriksa apakah suatu variabel nol atau tidak diset adalah [ -z "${VAR:-}" ]. Cek saya apakah suatu variabel tidak kosong [ "${VAR:-}" ]. - Kevin Jin


-z adalah cara terbaik.

Pilihan lain yang saya gunakan adalah untuk mengatur variabel, tetapi dapat diganti oleh variabel lain misalnya

export PORT=${MY_PORT:-5432}

Jika itu $MY_PORT variabel kosong, lalu PORT diatur ke 5432, jika PORT diatur ke nilai MY_PORT. Perhatikan sintaksnya termasuk titik dua dan tanda pisah.


36
2018-06-11 13:19



Secara tidak sengaja menemukan ini hari ini, dan itulah yang saya inginkan. Terima kasih! Saya harus mentolerir set -o nounset di beberapa skrip. - opello


Jika Anda tertarik untuk membedakan kasus status set-empty versus unset, lihat opsi -u untuk bash:

$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR

$ [ -z "$BAR" ] && echo true
true

24
2018-05-12 18:21





Sebuah alternatif yang pernah saya lihat [ -z "$foo" ] adalah yang berikut, namun saya tidak yakin mengapa orang menggunakan metode ini, ada yang tahu?

[ "x${foo}" = "x" ]

Lagi pula jika Anda tidak mengizinkan variabel yang tidak disetel (baik oleh set -u atau set -o nounset), maka Anda akan mendapat masalah dengan kedua metode tersebut. Ada perbaikan sederhana untuk ini:

[ -z "${foo:-}" ]

Catatan: ini akan meninggalkan variabel undef Anda.


8
2017-10-20 03:58



Ada komentar tentang alternatifnya -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 bisa meluas ke sesuatu yang diawali dengan metacharacter itu [ atau test akan bingung oleh. Menempatkan non-metacharacter sewenang-wenang pada awalnya menghilangkan kemungkinan itu. - James Sneeringer


Itu pertanyaan bertanya cara memeriksa apakah suatu variabel adalah string kosong dan jawaban terbaik sudah diberikan untuk itu.
Tapi saya mendarat di sini setelah periode berlalu pemrograman di php dan apa yang saya cari sebenarnya adalah cek seperti fungsi kosong di php bekerja di shell bash.
Setelah membaca jawaban, saya menyadari bahwa saya tidak berpikir dengan benar dalam bash, tetapi bagaimanapun juga suatu fungsi seperti itu kosong di php akan sangat berguna dalam kode bash saya.
Karena saya pikir ini bisa terjadi pada orang lain, saya memutuskan untuk mengonversi fungsi kosong php di bash

Menurut php manual:
variabel dianggap kosong jika tidak ada atau jika nilainya adalah salah satu dari yang berikut:

  • "" (string kosong)
  • 0 (0 sebagai bilangan bulat)
  • 0,0 (0 sebagai pelampung)
  • "0" (0 sebagai string)
  • array kosong
  • sebuah variabel dideklarasikan, tetapi tanpa nilai

Tentu saja batal dan Salah Kasus tidak dapat dikonversi dalam bash, sehingga mereka 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 passed
    if test -z "$var"
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is zero (0 as an integer or "0" as a string)
    elif [ "$var" == 0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is 0.0 (0 as a float)
    elif [ "$var" == 0.0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return
    fi

    [[ $( echo "" ) ]]
}



Contoh penggunaan:

if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



Demo:
cuplikan berikut:

#!/bin/bash

vars=(
    ""
    0
    0.0
    "0"
    1
    "string"
    " "
)

for (( i=0; i<${#vars[@]}; i++ ))
do
    var="${vars[$i]}"

    if empty "${var}"
        then
            what="empty"
        else
            what="not empty"
    fi
    echo "VAR \"$var\" is $what"
done

exit

output:

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, pemeriksaan nol dalam fungsi ini dapat menyebabkan masalah sampingan imho, siapa pun yang menggunakan fungsi ini harus mengevaluasi risiko ini dan mungkin memutuskan untuk memotong cek tersebut sehingga hanya meninggalkan yang pertama.


6
2017-08-31 20:11



Di dalam fungsi empty - mengapa kamu menulis [[ $( echo "1" ) ]] ; return bukan hanya return 1 ? - Dor