2010-09-26 11 views
11

neden yapar:bash veya ve eğer olumsuzlama

#!/bin/bash 
wtf=false 
if [ $wtf ] || [ ! -f filethatexists.whatever ] 
then 
echo "WTF1" 
fi 
if [ ! -f filethatexists.whatever ] 
then 
echo "WTF2" 
fi 

baskı:

WTF1

yerine hiçbir şey? Özellikle, ikinci formun beklendiği gibi çalıştığını ve ilkinin değil de şaşırtıcıdır. ortada dize boş olup olmadığını

cevap

10

temel test

[ $wtf ] 

testleri. $wtf yana

dize 'false' içeren, sınama doğru döner, ya da başarı için çıkış durumu 0, 'false' boş bir dize '' aynı değildir - çünkü ve dolayısıyla sen cevap olarak WTF1 olsun. ile

Dene:

wtf='' 

olarak Gordon Davisson (ve Dennis Williamson) tarafından işaret, test ettiğiniz dizeleriyle dikkatli olmak için iyi bir fikirdir. Gerçekten de, bir değişkenin ayarlanıp ayarlanmadığını test etmek için her zaman [ -n "$wtf" ] veya [ -z "$wtf" ] kullanacağımı belirtmeliydim, çünkü bu kabuk, çeyrek asır önce bir zamanlar kabuk öğrenirken gerekliydi. Bash'taki endişe duydukları hikayelerden ötürü Bash'de endişelenmenize gerek yok - ama bence buradaki kod, bunun hakkında hala endişelenmeniz gereken bir karşı örnek sunuyor. Asılları çift tırnak değişkenleri test

  • , ya da (Bash)
  • , değişken genişleme nasıl işleneceğini biliyor [[ $wtf ]] kullanın: Yani

    , bazı en iyi uygulamalar.
  • Boş veya boş olmayan değerleri sınamak için -n veya -z testlerini kullanın.

Kurallarda istisnalar olabilir - ancak bunları takip etmekte yanlış olmazsınız.

wtf="1 -eq 0" 
[ $wtf ] && echo "WTF0" 
[[ $wtf ]] && echo "WTF1" 
wtf="false" 
[ $wtf ] && echo "WTF2" 
[[ $wtf ]] && echo "WTF3" 
wtf="" 
[ $wtf ] && echo "WTF4" 
[[ $wtf ]] && echo "WTF5" 
wtf="false" 
[ "$wtf" ] && echo "WTF6" 
[[ "$wtf" ]] && echo "WTF7" 
wtf="" 
[ "$wtf" ] && echo "WTF8" 
[[ "$wtf" ]] && echo "WTF9" 

üretir:

WTF1 
WTF2 
WTF3 
WTF6 
WTF7 

'Bash testcode.sh' veya çalıştırmak, MacOS X 10.6.4 bulunan olarak yumrukluyorlar ksh (her ikisi de

kod göz 'ksh testcode.sh'). Gerçek bir Bourne kabuğu (eğer hala böyle bir şey bulabilirseniz) çift-braket işlemlerine itiraz eder - $PATH'da ' [[' komutunu bulamazdı.

Daha fazla vaka ad nauseam'ı kapsayacak şekilde test süresini uzatabilirsiniz.

+0

ok, anlamlıdır. Sözdizimi vurgulama bana, boollerin belli olduğu bir şey yaptı. Tahminimce çok bekledim. – i30817

+0

Aslında, bundan bile daha gariptir - eğer $ wtf içinde boşluk varsa, bu bir ifade olarak değerlendirilecektir. Efekti görmek için wtf = "1 -eq 0" ve wtf = "1 -eq 1" ile deneyin. Daha da fazla komedi için, 'wtf =" 1 -eq "yi deneyin. –

+0

Test 4/5 8/9 testinin iki kopyasına denk geldiğimde, değişkenin etrafında alıntı yapmadan 4/5 yapman gerektiğini düşünmekteyim (fakat sonuç aynı - hiçbir şey yankılanmıyor) Ayrıca, değişkene atıfta bulunarak test 0/1 değiştirilmemiş '1 -eq 0' böylece her iki braket türü doğru olarak değerlendirilir (test 2/3'te olduğu gibi). İlginçtir, Bash ve ksh, '['']', '[['']]' ve '[]' Çalıştırın ve yanlış döndürün, ancak [[]] 'bir hata üretir –

0

if [ $wtf = true ] || [ ! -f . .

+0

veya" if [[$ wtf == true]] || [! -f ... " – dimba

3

Burada kullanışlı küçük hüner: Bu formda

wtf=false 
if $wtf || [ ! -f filethatexists.whatever ] 

, değişkenin içeriğinin yürütülür ve test başarılı veya başarısız olursa bir dönüş değeri tespit etmektedir. true ve false, uygun değeri döndüren Bash yerleşikleri olur.

+1

Bu" kullanışlı küçük hile "pek iyi bir uygulamadır.Eğer' wtf' '' true' veya 'false' dışında bir şey içerdiği bir codepath varsa, şaşırtıcı davranış sonuçları. $? 'üzerinde taşır! rm -rf /'? Err ... –