pengembangan-web-mp-pd.com

Bagaimana cara menentukan apakah variabel bash kosong?

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

Saya telah mendengar bahwa disarankan agar saya melakukan if [ "x$variable" = "x" ]

Apakah itu benar jalan? (pasti ada sesuatu yang lebih mudah)

784
Brent

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

if [ -z "$VAR" ];
1075
duffbeer703

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:

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

Di Bash, menggunakan tanda kurung ganda, tanda kutip tidak diperlukan. Anda dapat menyederhanakan tes untuk variabel yang tidak berisi 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.

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):

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

di mana "x" adalah arbitrer.

Jika Anda ingin tahu apakah suatu variabel adalah nol tetapi tidak disetel:

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

Variabel dalam bash (dan 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 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 praktis:

                        +-------+-------+-----------+
                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      |
+-----------------------+-------+-------+-----------+

${VAR+foo} construct memperluas ke string kosong jika VAR tidak disetel atau ke foo jika VAR disetel ke apa pun (termasuk string kosong).

${VAR-foo} construct memperluas ke nilai VAR jika disetel (termasuk set ke string kosong) dan foo jika tidak disetel. Ini berguna untuk memberikan default yang dapat ditimpa pengguna (mis., ${COLOR-red} mengatakan untuk menggunakan red kecuali variabel COLOR telah disetel ke 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) buggy. Jika VAR diset ke sesuatu seperti -n, maka beberapa implementasi akan melakukan hal yang salah ketika diberikan [ "${VAR}" = "" ] karena argumen pertama ke [ ditafsirkan secara keliru sebagai -n operator, bukan string.

239
Richard Hansen

-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_PORT variabel kosong, maka PORT diset ke 5432, jika PORT diatur ke nilai MY_PORT. Perhatikan sintaksisnya termasuk titik dua dan tanda hubung.

38
Rory

Jika Anda tertarik membedakan kasus status set-kosong versus tidak disetel, 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
MikeyB

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

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

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

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

Catatan: ini akan membuat variabel Anda undef.

8
errant.info

Pertanyaan menanyakan cara memeriksa apakah suatu variabel adalah 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 dalam bash, tetapi 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 php kosong di bash

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

  • "" (string kosong)
  • 0 (0 as an integer)
  • 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, jadi 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, 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-cek itu hanya menyisakan yang pertama .

6
Luca Borrione

5 sen saya: ada juga sintaks yang lebih pendek dari 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 di abs-guide (mencari "Contoh 10-7").

5
gluk47

seluruh if-then dan -z tidak perlu.

 ["$ foo"] && echo "foo tidak kosong" 
 ["$ foo"] || gema "foo memang kosong" 
5
namewithoutwords

Ini benar ketika $ FOO disetel dan kosongkan:

[ "${FOO+x}" = x ] && [ -z "$FOO" ]
4
JHS

ekstensi oneliner dari duffbeer7 solusi:

#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
4
andrej

Secara pribadi lebih suka cara yang lebih jelas untuk memeriksa:

if [ "${VARIABLE}" == "" ]; then
  echo VARIABLE is empty
else
  echo VARIABLE is not empty
fi
4
Fedir RYKHTIK

Bukan jawaban yang pasti, tetapi mengalami trik ini. Jika string yang Anda cari berasal dari "a command" maka Anda sebenarnya dapat menyimpan perintah 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:

IS_DEBIAN="grep -i debian /proc/version"

if $IS_DEBIAN; then
  echo 'yes debian'
else
  echo 'non debian'
fi

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).

0
rogerdpack