2010-09-26 17 views
11

क्यों करता है:बैश के साथ या और अगर निषेध

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

प्रिंट:

WTF1

कुछ नहीं के बजाय? यह विशेष रूप से परेशान है कि दूसरा रूप अपेक्षित के रूप में काम करता है और पहला नहीं।

उत्तर

10

बुनियादी परीक्षण

[ $wtf ] 

परीक्षण है कि क्या बीच में स्ट्रिंग खाली है या नहीं।

$wtf के बाद से स्ट्रिंग 'false' होता है, परीक्षण सच लौटाता है, या सफलता के लिए बाहर निकलें स्थिति 0, क्योंकि 'false' रिक्त स्ट्रिंग '' के रूप में ही नहीं है - और इसलिए आप प्रतिक्रिया के रूप में WTF1 मिलता है।

साथ

प्रयास करें:

wtf='' 

रूप Gordon Davisson (और Dennis Williamson) द्वारा ने कहा, यह एक अच्छा विचार तार है कि आप परीक्षण कर रहे हैं के साथ सावधान रहना है। दरअसल, मुझे यह कहना चाहिए था कि एक चर सेट करने के बाद मैं हमेशा [ -n "$wtf" ] या [ -z "$wtf" ] का उपयोग करता हूं यह जांचने के लिए कि एक चरम शताब्दी पहले, जब मैं शैल सीख रहा था, तब आवश्यक था। मेरे पास बैश afficionados से काउंटर कहानियां हैं कि आपको बैश में इसके बारे में चिंता करने की ज़रूरत नहीं है - हालांकि, मुझे लगता है कि यहां कोड एक उदाहरण प्रदान करता है कि वास्तव में आपको इसके बारे में चिंता करने की ज़रूरत है।

तो, कुछ सर्वोत्तम प्रथाओं:

  • संलग्न दोहरे उद्धरण में चर परीक्षण किया है, या
  • (बैश में), [[ $wtf ]] जो कैसे चर विस्तार को संभालने के लिए पता है का उपयोग करें।
  • -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" 

कि पैदा करता है:

WTF1 
WTF2 
WTF3 
WTF6 
WTF7 

दोनों बैश और ksh (जब 'बैश testcode.sh' या के साथ चलाने के रूप में, MacOS एक्स 10.6.4 पर पाया साथ

कोड पर विचार करें 'ksh testcode.sh')। एक असली बोर्न शेल (यदि आप अभी भी ऐसी चीज पा सकते हैं) डबल-ब्रैकेट ऑपरेशंस पर ऑब्जेक्ट करेगा - यह $PATH पर '[[' कमांड को नहीं ढूंढ पाएगा।

आप अधिक मामलों को कवर करने के लिए परीक्षण का विस्तार कर सकते हैं विज्ञापन मतली।

+0

ठीक है, समझ में आता है। सिंटैक्स हाइलाइटिंग ने मुझे यह बात की कि बूलियन दिए गए थे। मुझे लगता है कि मुझे बहुत उम्मीद है। – i30817

+0

असल में, यह उससे भी कमजोर है - अगर $ wtf में कोई रिक्त स्थान है, तो इसका मूल्यांकन एक अभिव्यक्ति के रूप में किया जाएगा। प्रभाव देखने के लिए इसे 'wtf = "1 -eq 0" 'और' wtf = "1 -eq 1' के साथ आज़माएं। और भी कॉमेडी के लिए,' wtf =" 1 -eq "' –

+0

टेस्ट 4/5 आज़माएं परीक्षण 8/9 का डुप्लिकेट। मुझे लगता है कि आपको वैरिएबल के चारों ओर उद्धरण के बिना 4/5 करना है (लेकिन नतीजा वही है - कुछ भी गूंज नहीं हुआ है)। इसके अलावा, वैरिएबल को उद्धृत करके 0/1 का परीक्षण किया गया है, इसका मूल्यांकन नहीं करता है '1 -eq 0' इसलिए दोनों ब्रैकेट प्रकार सत्य (जैसे परीक्षण 2/3 में) का मूल्यांकन करते हैं। दिलचस्प बात यह है कि बैश और क्ष में, '[' ']',' [['']] 'और '[]' प्रत्येक काम, और झूठी वापसी, हालांकि '[[]] 'एक त्रुटि उत्पन्न करता है। –

0

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

+0

या यहां तक ​​कि" अगर [[$ wtf == true]] || [! -f ... " – dimba

3

यहाँ एक आसान छोटे चाल है:

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

इस रूप में, चर की सामग्री को क्रियान्वित कर रहे हैं और परीक्षण गुजरता है या विफल रहता है कि क्या दिया गया मान निर्धारित करता है। ऐसा होता है कि true और false बैश बिल्टिन हैं जो उचित मूल्य लौटाते हैं।

+1

यह" आसान छोटी चाल "शायद ही अच्छी प्रैक्टिस है। यदि आपके पास कोडपैथ है जहां 'wtf' में' सत्य 'या' झूठी 'के अलावा कुछ भी है, तो आश्चर्यजनक व्यवहार परिणाम। खाली स्ट्रिंग?' $? 'खत्म हो गया!' आरएम-आरएफ/'? एर ... –

संबंधित मुद्दे