Soru Bir bash değişkeni boş olup olmadığını nasıl belirleyebilirim?


Bash'ta bir değişkenin boş olup olmadığını belirlemenin en iyi yolu nedir ("")?

Yapmamın tavsiye edildiğini duydum if [ "x$variable" = "x" ]

Bu mu doğru yolu? (Daha basit bir şey olmalı)


721
2018-05-12 17:54


Menşei




Cevaplar:


Bir değişken unset veya boş dizgeye ("") ayarlanmışsa bu, true olarak geri döner.

if [ -z "$VAR" ];

986
2018-05-12 18:06



Eğer bir değişken "SET" değerine "" katsayısı dahil mi? - Brent
Evet öyle ... "-z" sıfır uzunluklu bir dizeyi test eder. - David Z
if [ ! -z "$VAR" ]; - Aaron Copley
tersi -z olduğu -n  if [ -n "$VAR" ]; - Felipe Alvarez
Çift tırnaklar, değişkenin bölünmemesini sağlar. Basit $var bir komut satırında, boşlukları tarafından bir parametre listesine bölünür. "$var" her zaman sadece bir parametre olacaktır. Alıştırma değişkenleri genellikle iyi bir uygulamadır ve beyaz boşluk içeren dosya adlarında (diğer şeylerin yanı sıra) sizi durdurmanızı engeller. Örnek: yaptıktan sonra a="x --help", Deneyin cat $a - size yardım sayfasını verecektir cat. O zaman dene cat "$a" - (genellikle) söyleyecektir cat: x --help: No such file or directory. Kısacası, erken alıntı yapın ve sık sık alıntı yapın ve neredeyse hiç pişman olmayacaksınız. - Score_Under


Bash'de, desteklemeyen kabuklara taşınabilirlikle ilgilenmediğinizde, her zaman çift destekli sözdizimini kullanmanız gerekir:

Aşağıdakilerden herhangi biri:

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

Bash'de, çift köşeli parantez kullanarak teklifler gerekli değildir. Bu testi bir değişken için basitleştirebilirsiniz. yapar için bir değer içerir:

if [[ $variable ]]

Bu sözdizimi ksh ile uyumludur (en azından ksh93, yine de). Saf POSIX veya sh veya tire gibi eski Bourne kabuklarında çalışmaz.

Görmek benim cevabım burada ve BashFAQ / 031 Çift ve tek köşeli parantez arasındaki farklar hakkında daha fazla bilgi için.

Bir değişkenin özellikle belirsiz olup olmadığını (boş bir dizeden farklı olarak) test edebilirsiniz:

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

"x" nin keyfi olduğu yer.

Bir değişkenin null olup olmadığını anlamak için unset:

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

227
2018-02-25 03:37



o if [[ $variable ]] benim için iyi çalıştı ve hatta set -u Bu, önerilen diğer çözümlerden biri tarafından gerekliydi. - Teemu Leisti
Bunun kabul edilen cevaptan daha iyi olduğunu düşünüyorum. - qed
Neden böyle bir yararı olmayan bir özellik öneriyorsunuz? - Alastair Irvine
@AlastairIrvine: Ben cevabımın ilk cümlesinde taşınabilirlikten bahsetmiştim, soru başlığı ve gövde "Bash" kelimesini içerir ve soru etiketlenir darbeve çift braket yapısı sağlar net avantajlar birçok yoldan. Tutarlılık ve süreklilik nedenlerinden dolayı braket stillerini karıştırma önerilmiyorum. Maksimum, en düşük ortak payda taşınabilirliğine ihtiyacınız varsa, kullanın sh Bash yerine. Sağladığı artırılmış yeteneklere ihtiyacınız varsa, Bash'i kullanın ve tamamen kullanın. - Dennis Williamson
@BrunoBronosky: Düzenlemeyi geri aldım. Gerek yok ; sonunda. then Bir noktalı virgül olmadan bir sonraki hatta olabilir. - Dennis Williamson


Bash'ta bir değişken (ve herhangi bir POSIX uyumlu kabuk) üç durumdan birinde olabilir:

  • unset
  • boş dizeye ayarla
  • boş olmayan bir dizeye ayarlı

Çoğu zaman bir değişkenin boş olmayan bir dizgiye ayarlanıp ayarlanmadığını bilmeniz gerekir, ancak zaman zaman, unset ve boş dizgeyi ayarlamak arasında ayrım yapmak önemlidir.

Aşağıdakiler çeşitli olasılıkları nasıl test edebileceğinize dair örneklerdir ve bash veya POSIX uyumlu kabukta çalışır:

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

İşte aynı şey ama kullanışlı masa formunda:

                        +-------+-------+-----------+
                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} yapı boş dizeye genişlerse VAR unset veya foo Eğer VAR herhangi bir şeye ayarlanır (boş dizge dahil).

${VAR-foo} yapı değerine doğru genişler VAR ayarlanmışsa (boş dizgiye dahil) ve foo unset ise. Bu, kullanıcı tarafından yazılabilen varsayılanların sağlanması için yararlıdır (ör. ${COLOR-red} kullanmak diyor red değişmezse COLOR bir şeye ayarlanmıştı).

Nedeni [ x"${VAR}" = x ] genellikle bir değişkenin ya dizilmemiş ya da boş dizgeye ayarlanıp ayarlanmadığını test etmek için önerilir çünkü bazı uygulamaların [ komutu (olarak da bilinir test) arabası vardır. Eğer VAR gibi bir şey olarak ayarlandı -nDaha sonra bazı uygulamalar yanlış verildiğinde [ "${VAR}" = "" ] çünkü ilk argüman [ hatalı olarak yorumlanır -n operatör, bir dize değil.


205
2018-04-24 20:39



Boş dizeye ayarlanmış bir değişken için test yapmak da kullanılarak yapılabilir. [ -z "${VAR-set}" ]. - nwellnhof
@nwellnhof: Teşekkürler! Ben kısayol sözdizimini kullanmak için cevabımı güncelledim. - Richard Hansen
@FaheemMitha: Bu senin suçun değil - cevabım okumak zordu. Umarım cevabı daha açık hale getirmek için bir tablo ekledim. - Richard Hansen
@RichardHansen: Teşekkürler, bu yararlı bir katkı. - Faheem Mitha
Kontrolsüz çekler güvenilir değil. Kullanıcı aradıysa set -u veya set -o nounset bash, sonra test sadece "bash: VAR: unbound variable" hatasıyla sonuçlanacaktır. Görmek stackoverflow.com/a/13864829 daha güvenilir bir unset kontrolü için. Bir değişkenin null mı yoksa unset olup olmadığını kontrol et [ -z "${VAR:-}" ]. Değişkenin boş olmadığını kontrol et [ "${VAR:-}" ]. - Kevin Jin


-z en iyi yoldur.

Kullandığım diğer bir seçenek, bir değişken ayarlamaktır, ancak başka bir değişken tarafından geçersiz kılınabilir örn.

export PORT=${MY_PORT:-5432}

Eğer $MY_PORT değişken boş, sonra PORT 5432'ye ayarlanır, aksi halde PORT değeri MY_PORT. Sözdizimi, iki nokta üst üste ve çizgi içeren not alın.


36
2018-06-11 13:19



Yanlışlıkla bugün bunu buldum ve istediğim tam olarak buydu. Teşekkürler! Tahammül etmeliyim set -o nounset bazı senaryolarda. - opello


Set-empty ve unset status durumlarını ayırt etmek istiyorsanız, bash için -u seçeneğine bakın:

$ 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





Gördüğüm bir alternatif [ -z "$foo" ] Aşağıdakiler, ancak insanların neden bu yöntemi kullandıklarını bilemiyorum, bilen var mı?

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

Her iki durumda da, değişkenleri izin vermezseniz set -u veya set -o nounset), o zaman bu yöntemlerin her ikisi de belaya girer. Bunun için basit bir düzeltme var:

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

Not: Bu değişkeninizi undef bırakacaktır.


8
2017-10-20 03:58



Alternatif hakkında bir yorum var -z en pubs.opengroup.org/onlinepubs/009695399/utilities/test.html. Temel olarak, bu bir alternatif olmak anlamına gelmez -z. Aksine, davaları nerede ele alır $foo bir metakarakter ile başlayan bir şeye genişleyebilir [ veya test tarafından karıştırılacaktı. Başlangıçta keyfi olmayan bir metakarakter koymak, bu olasılığı ortadan kaldırır. - James Sneeringer


soru sorar Bir değişkenin boş bir dize olup olmadığını kontrol etme ve bunun için en iyi cevaplar zaten verilmiş.
Ama bir süre sonra php programına geçtikten sonra buraya indim ve aslında aradığım şey bir kontrol gibiydi. php'de boş fonksiyon Bir bash kabuğunda çalışıyor.
Cevapları okuduktan sonra, bash'ta düzgün düşünmediğimi farkettim, ama o andaki gibi bir fonksiyon boş php'de, bash kodumda kullanışlı olacaktı.
Bunun başkalarına da olabileceğini düşündüğümden, php boş fonksiyonunu bash olarak değiştirmeye karar verdim

Göre php kılavuzu:
Bir değişken mevcut değilse veya değeri aşağıdakilerden biri ise boş olarak kabul edilir:

  • "" (boş bir dize)
  • 0 (tamsayı olarak 0)
  • 0,0 (bir kayan nokta olarak 0)
  • "0" (dize olarak 0)
  • boş bir dizi
  • bildirilen bir değişken, ancak bir değer olmadan

Tabiki boş ve yanlış davalar bash'a dönüştürülemez, dolayısıyla ihmal edilir.

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 "" ) ]]
}



Kullanım örneği:

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



Demo:
aşağıdaki kod parçacığı:

#!/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

çıktılar:

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

Bir bash mantığında bu fonksiyonda sıfırın kontrol edilmesinin yan problemlere neden olabileceğini söyleyerek, bu fonksiyonu kullanan herkes bu riski değerlendirmeli ve bu kontrolleri sadece ilkini bırakarak kesmeye karar verebilir.


6
2017-08-31 20:11



Fonksiyonun içinde empty - neden yazdın [[ $( echo "1" ) ]] ; return basitçe yerine return 1 ? - Dor


tüm-sonra ve -z gereksizdir.

["$ foo"] && echo "foo boş değil"
["$ foo"] || echo "foo gerçekten boş"

5
2018-01-26 14:02



Eğer foo sadece boşluk içeriyorsa bu başarısız olur. - Brian
Ayrıca bazı kabuklarda da başarısız olur foo bir seçenek olarak yorumlandığı için bir tire ile başlar. Örneğin. solaris üzerinde ksh, zsh ve darbe sorun değil sh ve / Bin / test başaramayacak - ktf


Bu tam olarak $ FOO ayarlandığında ve boş olduğunda geçerlidir:

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

4
2018-05-20 20:52