"GNU bash, Sürüm 4.2" öncesi Bash sürümleri -viçin testkomut 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 -viçin testkomut 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 foobaraynı şekilde boş ya da değil tanımlanmış olup olmadığı. Ayrıca tanımsız ${foobar-}olduğunda boş bir dize foobarve foobaraksi takdirde (veya değerinden sonra başka bir varsayılan değer koyabilirsiniz) almak için de kullanabilirsiniz -.
Ksh olarak, eğer foobarbildirilen 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 foobarboş bir dizi oluşturur.
Bash'da, diziler farklı ve şaşırtıcı bir şekilde davranır. ${a+1}yalnızca boş olmayan bir dizi 1olduğ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 foobardeclare -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 $foobaraltında bir hataya neden olacaksa boş dizeye genişlediğini unutmayın set -o nounset.
echo "${foobar:+1}"yazdırmıyor 1ise declare -a foobar, daha önce yayınlanmış ve böylece foobardizinlenmiş dizidir. declare -p foobardoğ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 “ $foobaraltı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.
0dizin ne de bir anahtar doğru olarak tanımlanmazsa a=(), ${a+1}hiçbir şey doğru olarak döndürmez.
definedoperatö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/nullBash <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-AdeclareBen 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.
-vbir seçenek değiltest, koşullu ifadeler için bir operatördür.