"GNU bash, Sürüm 4.2" öncesi Bash sürümleri -v
için test
komut seçeneği için eşdeğer alternatifler var mı? Örneğin:
shopt -os nounset
test -v foobar && echo foo || echo bar
# Output: bar
foobar=
test -v foobar && echo foo || echo bar
# Output: foo
"GNU bash, Sürüm 4.2" öncesi Bash sürümleri -v
için test
komut seçeneği için eşdeğer alternatifler var mı? Örneğin:
shopt -os nounset
test -v foobar && echo foo || echo bar
# Output: bar
foobar=
test -v foobar && echo foo || echo bar
# Output: foo
Yanıtlar:
Tüm POSIX mermilerine taşınabilir:
if [ -n "${foobar+1}" ]; then
echo "foobar is defined"
else
echo "foobar is not defined"
fi
Emin olun ${foobar:+1}
Eğer tedavi etmek istiyorsanız foobar
aynı şekilde boş ya da değil tanımlanmış olup olmadığı. Ayrıca tanımsız ${foobar-}
olduğunda boş bir dize foobar
ve foobar
aksi takdirde (veya değerinden sonra başka bir varsayılan değer koyabilirsiniz) almak için de kullanabilirsiniz -
.
Ksh olarak, eğer foobar
bildirilen değil, olduğu gibi tanımlanan typeset -a foobar
, daha sonra ${foobar+1}
boş bir dizeye genişler.
Zsh, bildirilen ancak ayarlanmayan değişkenlere sahip değil: typeset -a foobar
boş bir dizi oluşturur.
Bash'da, diziler farklı ve şaşırtıcı bir şekilde davranır. ${a+1}
yalnızca boş olmayan bir dizi 1
olduğunda genişler a
, ör.
typeset -a a; echo ${a+1} # prints nothing
e=(); echo ${e+1} # prints nothing!
f=(''); echo ${f+1} # prints 1
İlişkilendirilebilir diziler için de aynı ilke geçerlidir: dizi değişkenleri, boş olmayan bir dizin dizisine sahiplerse tanımlandığı gibi işlenir.
Herhangi bir türün değişkeninin tanımlanıp tanımlanmadığını test etmenin farklı, bash'a özgü bir yolu, listede listelenip listelenmediğini kontrol etmektir . Bu, boş dizileri tanımlandığı gibi bildirir, ancak bildirilen ancak atanmamış değişkenleri ( ) tanımsız olarak bildirir .${!PREFIX*}
${foobar+1}
unset foobar; typeset -a foobar
case " ${!foobar*} " in
*" foobar "*) echo "foobar is defined";;
*) echo "foobar is not defined";;
esac
Bu, bildirilen ancak atanmamış değişkenlerin başarısız olması dışında veya döndürülen değerinin test edilmesinetypeset -p foobar
declare -p foobar
eşdeğerdir typeset -p foobar
.
Bash öğesinde, ksh öğesinde olduğu gibi set -o nounset; typeset -a foobar; echo $foobar
, tanımsız değişkeni genişletme girişiminde bir hata tetikler foobar
. Ksh'den farklı olarak, set -o nounset; foobar=(); echo $foobar
(veya echo "${foobar[@]}"
) bir hata da tetikler.
Burada açıklanan tüm durumlarda, ${foobar+1}
yalnızca $foobar
altında bir hataya neden olacaksa boş dizeye genişlediğini unutmayın set -o nounset
.
echo "${foobar:+1}"
yazdırmıyor 1
ise declare -a foobar
, daha önce yayınlanmış ve böylece foobar
dizinlenmiş dizidir. declare -p foobar
doğru raporlar declare -a foobar='()'
. Does "${foobar:+1}"
dizi olmayan değişkenler için tek işi?
${foobar+1}
(olmadan, :
orijinal cevabımda iki örneği tersine çevirdim ), “tanımlanmış” tanımınız “ $foobar
altında çalışır ” ise bash dizileri için doğrudur set -o nounset
. Tanımınız farklıysa, bash biraz garip. Güncellenmiş cevabımı görün.
0
dizin ne de bir anahtar doğru olarak tanımlanmazsa a=()
, ${a+1}
hiçbir şey doğru olarak döndürmez.
defined
operatörü var. Test
bunu yapabilirdi ; o (zor olamaz um ....)
Gilles'in cevabını özetlemek için aşağıdaki kurallarımı oluşturdum:
[[ -v foobar ]]
Bash sürümünde değişkenler için kullanın > = 4.2.declare -p foobar &>/dev/null
Bash <4.2 sürümündeki dizi değişkenleri için kullanın .(( ${foo[0]+1} ))
veya kullanın . Seçenek 1 ve 2 burada çalışmıyor.(( ${bar[foo]+1} ))
-a
-A
declare
Ben bash tüm değişkenler için aynı tekniği kullanın ve çalışır, örneğin:
[ ${foobar} ] && echo "foobar is set" || echo "foobar is unset"
çıktılar:
foobar is unset
İken
foobar=( "val" "val2" )
[ ${foobar} ] && echo "foobar is set" || echo "foobar is unset"
çıktılar:
foobar is set
foobar=""
bunu rapor edeceğim foobar is unset
. Bekleme yok, onu geri alıyorum. Gerçekten sadece ilk eleman boş olup olmadığını test eder, bu yüzden değişkenin bir dizi DEĞİL olduğunu biliyorsanız iyi bir fikir gibi görünüyor ve sadece tanım boşluğu değil, boşluğu önemsiyorsunuz.
-v
bir seçenek değiltest
, koşullu ifadeler için bir operatördür.