Aşağıdaki kod, ilişkisiz bir değişken hatasıyla çıkar. Hala set -o
isim seti seçeneğini kullanırken bunu nasıl düzeltebilirim ?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
Yanıtlar:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
Bu durumda, ayarlanmamışsa VALUE
boş bir dize olur WHATEVER
. "Parametre Genişletme" altında {parameter:-word}
bakabileceğiniz genişletmeyi kullanıyoruz man bash
.
:-
değişkenin ayarlanmamış veya boş olup olmadığını kontrol eder . Eğer kontrol etmek isterseniz sadece o tanımsız olsun, kullanın -
: VALUE=${WHATEVER-}
. Ayrıca, bir değişkenin boş olup olmadığını kontrol etmenin daha okunaklı bir yolu:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVER
yalnızca boşluk içeriyorsa bu işe yaramaz - Cevabıma bakın.
! -z
Sadece " -n
" yerine " " kullanmanın bir nedeni var mı ?
Beklediğiniz sonucu elde etmek istiyorsanız değişkenleri alıntı yapmanız gerekir:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Ölçek:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
"info bash"
, "${WHATEVER-}"
bir olması gereken ":"
önce (iki nokta üst üste) "-"
: gibi (tire) "${WHATEVER:-}"
ve "${WHATEVER+defined}"
daha önce iki nokta üst üste sahip olmalıdır "+"
(artı) gibi: "${WHATEVER:+defined}"
. Benim için, iki nokta üst üste olsun veya olmasın her iki şekilde de çalışır. 'Nix'in bazı sürümlerinde, büyük olasılıkla iki nokta üst üste eklemeden çalışmayacaktır, bu nedenle muhtemelen eklenmelidir.
-
, +
, :+
, ve :-
tüm desteklenmektedir. Eski değişken olup olmadığını tespit ayarlanır ve ikinci bu olup olmadığını tespit set ya da boş . Kimden man bash
: "İki nokta üst üste işaretinin çıkarılması, yalnızca ayarlanmamış bir parametre için bir teste neden olur."
Bir oneliner'e ne dersiniz?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z
hem boş hem de ayarlanmamış değişken için kontrol eder
-z
yalnızca sonraki parametrenin boş olup olmadığını kontrol eder. -z
sadece [
komutun bir argümanıdır . Değişken genişleme bir şey yapmadan önce gerçekleşir [ -z
.
Varsayımlar:
$ 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
Etkileşimli olmayan bir komut dosyasının bir hata yazdırmasını ve bir değişken boşsa veya ayarlanmamışsa çıkmasını istiyorsanız:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
Komut dosyasının çıkmasını istemiyorsanız:
$ [[ "${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.
Hatta kullanabilir [
ve ]
yerine [[
ve]]
üstünü kullanabilirsiniz, ancak ikincisi Bash'de tercih edilir.
Kolonun yukarıda ne yaptığına dikkat edin. Gönderen docs :
Başka bir deyişle, kolon dahil edilmişse, operatör hem parametrenin varlığını hem de değerinin boş olmadığını test eder; iki nokta üst üste belirtilmezse, operatör yalnızca var olup olmadığını test eder.
Görünüşe göre -n
ya da gerek yok -z
.
Özetle, genellikle sadece kullanabilirim [[ "${VAR:?}" ]]
. Örneklere göre, bu bir hata yazdırır ve bir değişken boşsa veya ayarlanmamışsa çıkar.
Kullanabilirsiniz
if [[ ${WHATEVER:+$WHATEVER} ]]; then
fakat
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
daha okunaklı olabilir.
=
değil ==
ve mümkünse [
bunun yerine standart (POSIX) operatörünü kullanmalıdır [[
.
set -o nounset
. #!/bin/bash
Betiğinizin üstüne bir koyarsanız , aslında en iyisi bash'ın geliştirmelerini kullanmaktır.
Bu tam olarak yukarıda istenen kullanım durumu olmasa da , kullanmak istiyorsanız nounset
(veya-u
) varsayılan davranışın istediğiniz davranış olduğunu : açıklayıcı bir mesajla sıfırdan farklı çıkmak.
Çözüm olarak yayınlamaya değer olduğunu düşündüğümü fark etmem yeterince uzun sürdü.
İstediğiniz tek şey çıkarken başka bir şeyi yankılamaksa veya biraz temizlik yapmaksa, bir tuzak kullanabilirsiniz.
:-
Operatör aksi istediğini olasılıkla gerçek değildir.