Bash'deki bir değişkenin boş ("") olup olmadığını belirlemenin en iyi yolu nedir?
Yapmamın tavsiye edildiğini duydum. if [ "x$variable" = "x" ]
Böyle mi doğru yolu? (daha basit bir şey olmalı)
Bash'deki bir değişkenin boş ("") olup olmadığını belirlemenin en iyi yolu nedir?
Yapmamın tavsiye edildiğini duydum. if [ "x$variable" = "x" ]
Böyle mi doğru yolu? (daha basit bir şey olmalı)
Yanıtlar:
Bir değişken atanmamışsa veya boş dizgeye ("") ayarlanmışsa bu, true değerini döndürür.
if [ -z "$VAR" ];
if [ ! -z "$VAR" ];
-z
olan-n
if [ -n "$VAR" ];
$var
komut satırındaki basit bir boşlukla beyaz bir parametre listesine bölünürken "$var"
, her zaman yalnızca bir parametre olacaktır. Değişkenleri alıntılamak çoğu zaman iyi bir uygulamadır ve beyaz boşluk içeren dosya adlarını açmanızı engeller (diğer şeylerin yanı sıra). Örnek: Yaptıktan sonra a="x --help"
, deneyin cat $a
- size yardım sayfasını verecektir cat
. Sonra deneyin cat "$a"
- (genellikle) söyler cat: x --help: No such file or directory
. Kısacası, erken teklif ve sık sık teklif ve neredeyse hiç pişman olmayacaksınız.
Bash'te, desteklemeyen mermilerin taşınabilirliği ile ilgilenmiyorsanız, her zaman çift köşeli sözdizimini kullanmalısınız:
Aşağıdakilerden herhangi biri:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
Bash'te, çift köşeli ayraçlar kullanıldığında, alıntılar gerekli değildir. Bir değişken için testi kolaylaştırabilirsiniz yapar bir değer için içerir:
if [[ $variable ]]
Bu sözdizimi ksh ile uyumludur (en azından ksh93, yine de). Saf POSIX veya sh veya dash gibi daha eski Bourne mermilerinde çalışmaz.
Çift ve tek köşeli parantezler arasındaki farklar hakkında daha fazla bilgi için buradaki cevabımı ve BashFAQ / 031'e bakınız .
Bir değişkenin özel olarak belirsiz olup olmadığını test edebilirsiniz (boş bir dizgeden farklı olarak):
if [[ -z ${variable+x} ]]
burada "x" isteğe bağlı.
Bir değişkenin null olup olmadığını bilmek istiyorsanız, kümelenmemiş:
if [[ -z $variable && ${variable+x} ]]
if [[ $variable ]]
benim için iyi çalıştı ve set -u
önerilen diğer çözümlerden birinin gerektirdiği şeye bile ihtiyaç duymuyordu .
sh
, Bash yerine kullanın . Sağladığı yeteneklerin arttırılması gerekiyorsa, Bash'i kullan ve tamamen kullan.
;
sonunda. then
Hiç bir noktalı virgül olmadan sonraki satırda olabilir.
Bash'deki bir değişken (ve herhangi bir POSIX uyumlu kabuk) üç durumdan birinde olabilir:
Çoğu zaman yalnızca bir değişkenin boş olmayan bir dizeye ayarlanıp ayarlanmadığını bilmeniz gerekir, ancak bazen unset ve boş dizgiyi ayırmak önemlidir.
Aşağıdakiler, çeşitli olasılıkları nasıl test edebileceğinize ilişkin örnekler olup, bash veya POSIX uyumlu herhangi bir 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 şeklinde:
+-------+-------+-----------+
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}
Eğer yapı boş dizeye genişler VAR
ayarlanmazsa veya foo
eğer VAR
bir şey olarak ayarlanır (boş dize dahil).
${VAR-foo}
Yapı değerine kadar genişler VAR
set (boş bir dizeye ayarlanmış dahil) ve eğer foo
sertleşmemiş halinde. Bu, kullanıcı tarafından geçersiz kılınabilen varsayılanları sağlamak için kullanışlıdır (örneğin, değişken bir şeye ayarlanmadıkça ${COLOR-red}
kullanma der ).red
COLOR
Nedeni [ x"${VAR}" = x ]
bazı uygulamaları nedeniyle sık sık değişken ayarlanmazsa veya boş bir dizeye ayarlanmış ya olup olmadığını test etmek için tavsiye edilir olduğu [
(olarak da bilinir komutu test
) arabası vardır. Eğer VAR
böyle bir şeye ayarlanmışsa -n
, bazı uygulamalar hatalı yapıldığında yanlış bir şey yapacaktır, [ "${VAR}" = "" ]
çünkü ilk argüman bir dize değil [
, -n
operatör olarak yanlış yorumlanmıştır .
[ -z "${VAR-set}" ]
.
set -u
veya set -o nounset
bash ise, test sadece "bash: VAR: unbound değişken" hatasıyla sonuçlanacaktır. Daha güvenilir bir ayarsız kontrol için bkz. Stackoverflow.com/a/13864829 . Go-to-değişken bir null olup olmadığını kontrol etmek veya unset olup olmadığını [ -z "${VAR:-}" ]
. Bir değişkenin boş olmadığını kontrol ediyorum [ "${VAR:-}" ]
.
-z
en iyi yol budur.
Kullandığım diğer seçenekler değişken ayarlamak, ancak başka bir değişken tarafından geçersiz kılınabilir.
export PORT=${MY_PORT:-5432}
Eğer $MY_PORT
değişken boşsa PORT
aksi PORT değerine ayarlanır, 5432 ayarlı alır MY_PORT
. Sözdiziminde iki nokta üst üste ve kısa çizgi bulunur.
set -o nounset
Bazı senaryolara katlanmak zorundayım .
Gördüğüm bir alternatif [ -z "$foo" ]
şudur, ancak insanların neden bu yöntemi kullandıklarından emin değilim, herkes biliyor?
[ "x${foo}" = "x" ]
Her neyse, ayarlanmamış değişkenleri (ya da ya set -u
da set -o nounset
) reddediyorsanız , o zaman bu iki yöntemde de sorun yaşayacaksınız. Bunun basit bir çözümü var:
[ -z "${foo:-}" ]
Not: Bu değişkeninizi undef bırakacaktır.
-z
adresinde yorum yapıldı . Temel olarak, bunun bir alternatifi olmadığı anlamına gelmez -z
. Daha ziyade, $foo
bir meta karakteriyle başlayan [
veya test
karışması gereken bir şeye genişleyebilecek durumlarla ilgilenir . Rasgele bir meta karakter olmayanı başlangıçta koymak, bu olasılığı ortadan kaldırır.
Soru sorar bir değişken boş bir dize olup olmadığını kontrol etmek nasıl ve en iyi cevapları Zaten bunun için verilmiştir.
Fakat bir süre php ile programlamayı geçtikten sonra buraya inmiştim ve aslında aradığım şey php'deki bash kabuğundaki boş fonksiyon gibi bir kontrol .
Cevapları okuduktan sonra, bash'da düzgün düşünmediğimi fark ettim, ama o an php'da boş gibi bir fonksiyon bash kodumda çok kullanışlı olurdu.
Bunun diğerlerinden başına gelebilecek düşünürken, bash php boş fonksiyonunu dönüştürmek için karar
uyarınca php kılavuzu :
değişken yoksa veya değeri aşağıdakilerden biriyse boş kabul edilir:
Tabii ki boş ve yanlış durumlar bash olarak dönüştürülemez, bu nedenle 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 pasaj:
#!/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 işlevdeki sıfır üzerindeki çeklerin yan sorunlara neden olabileceğini söyleyerek, bu işlevi kullanan herkes bu riski değerlendirmeli ve belki de yalnızca ilkini bırakarak bu çekleri kesmeye karar vermelidir.
empty
- neden [[ $( echo "1" ) ]] ; return
basitçe yazdınız return 1
?
if-then ve -z'nin tamamı gereksizdir.
["$ foo"] && echo "foo boş değil" ["$ foo"] || yankı "foo gerçekten boş"
Bu tam olarak $ FOO ayarlanmış ve boşken geçerlidir:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Şahsen kontrol etmek için daha net bir yol tercih et:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
arasında oneliner uzantısı duffbeer703 'in çözeltisi:
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
5 sentim: Bundan daha kısa bir sözdizimi de var if ...
:
VALUE="${1?"Usage: $0 value"}"
Bir argüman sağlandıysa, bu satır VALUE olarak belirlenir ve bir hata olması durumunda komut satırı satırıyla birlikte hazırlanmış bir hata mesajı basar (ve komut çalıştırmasını sonlandırır).
Başka bir örnek abs-rehberinde bulunabilir («Örnek 10-7» için arama yapın).
Kesin bir cevap değil, ama bu numaraya rastladım. Eğer aradığınız dize "bir komuttan" geliyorsa, o zaman komutu bir env içinde saklayabilirsiniz. değişken ve ardından if ifadesi için her seferinde uygulayın, sonra parantez gerekmez!
Örneğin debian olup olmadığınızı belirleyen bu komut:
grep debian /proc/version
tam örnek:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
Bu, boş bir dize (her komuttan tekrarlanan) için boş bir dize denetleme (komuttan hata yanıtını denetleme olur, ancak boş bir dize döndürme olur) gibi dolaylı bir yol gibidir.