जबकि [0] अनंत लूप में जाता है?


23

मैं लूप के लिए नीचे के लूप के समान व्यवहार देखता हूं while [ 1 ]। ऐसा क्यों हैं?

while [ 0 ]; do
    echo "hello"
done

जवाबों:


33

शेल में सिंगल स्क्वायर ब्रैकेट test(या तो अलग कमांड या शेल-इन) के लिए एक समानार्थी शब्द है , इसलिए [ 0 ]इसका मतलब वही है test 0testफ़ाइलों की विशेषताओं की तुलना और परीक्षण करने के लिए है, जैसा कि आप इसके मैनपेज में पढ़ सकते हैं। जब इसे एक अभिव्यक्ति नहीं दी जाती है, जो तुलना, फ़ाइल परीक्षण, या ऐसा करने वाले अन्य कार्यों में से एक की तरह दिखता है, तो यह तर्क के मौजूद होने और गैर-रिक्त स्ट्रिंग के बजाय परीक्षण करेगा। न तो 0या 1परीक्षण के लिए वास्तव में उचित आदानों, कर रहे हैं और गैर-रिक्त स्ट्रिंग परीक्षण बस सफल होता है और अपने जबकि पाश हमेशा के लिए लूप के रूप में।

आप इसके बजाय प्रयास करना चाह सकते हैं

while false; do
  echo "hello"
done

संभवतः के falseसाथ बदल रहा है true। या हो सकता है कि आप क्या चाहते हैं (( )):

while (( 0 )); do
  echo "hello"
done

जो अधिकांश भाषाओं की तरह व्यवहार करेगा, जहाँ 0 का अर्थ है विफलता / असत्य और 1 का अर्थ है सफलता / सत्य।


1
पुन: "जब इसे एक अभिव्यक्ति नहीं दी जाती है जो तुलना, फ़ाइल परीक्षण, या किसी अन्य ऑपरेशन की तरह दिखती है, तो यह बस सफल होता है": मुझे नहीं लगता कि इसे लगाने का एक अच्छा तरीका है। आखिरकार, [ ](बिना किसी तर्क के) और [ "" ](एक भी खाली तर्क के साथ) सफल नहीं होते।
रुख

3
जैसा कि @ruakh बताते हैं, यह कथन गलत है: जब इसे एक अभिव्यक्ति नहीं दी जाती है जो तुलना, फ़ाइल परीक्षण, या किसी अन्य ऑपरेशन की तरह दिखती है, तो यह बस सफल होता है। परीक्षण करने के लिए किसी एक तर्क (वर्ग कोष्ठकों में किसी एक तर्क) सही माना जाता है यदि तर्क एक खाली स्ट्रिंग नहीं है, और दोनों 0और 1खाली स्ट्रिंग नहीं कर रहे हैं। नए शेल प्रोग्रामर अक्सर लिखते if [ 1=2 ]हैं if [ 1 = 2 ]और आश्चर्य करते हैं कि पूर्व हमेशा सच क्यों होता है। यह सच है क्योंकि यह एक एकल तर्क है और एक खाली स्ट्रिंग नहीं है।
इयान डी। एलन

अच्छे अंक, मैंने एक सुधार किया है।
विंगड्यूसम्ब्रेनर

10

यहाँ मान 0 एक संख्यात्मक स्थिरांक के रूप में काम नहीं कर रहा है, बल्कि एक चरित्र स्ट्रिंग के रूप में है। ये परीक्षण सफल समाप्ति की स्थिति उत्पन्न करने के उनके प्रभाव में सभी समान हैं:

[ A ]
[ "XYZ" ]
[ 0 ]

ये एक विफल समाप्ति स्थिति उत्पन्न करते हैं:

[ ]
[ "" ]

एक गैर-रिक्त तर्क है, जो तार्किक सत्य का मूल्यांकन करता है। यह आपको ऐसा करने की अनुमति देता है:

if [ $UNDER_NUCLEAR_ATTACK ] ; then
  launch-missiles -a $DRY_RUN  # $DRY_RUN set to "-n" during testing
fi

वेरिएबल UNDER_NUCLEAR_ATTACKसही इंगित करने के लिए किसी भी गैर-रिक्त मान पर सेट है, या गलत इंगित करने के लिए परेशान या खाली है।

हम !तर्क को उलटने के लिए ऑपरेटर को आवेदन कर सकते हैं :

[ ! a ]  # fails: a is nonblank so true; and not true is false.
[ ! ]    # succeeds: blank is false, not blank is true.

संख्यात्मक स्थिति का मूल्यांकन करने के लिए, आपको संख्यात्मक परीक्षण ऑपरेटरों का उपयोग करना होगा:

 while [ $A -gt $B ] ; do ...

अगर Aऔर Bइसमें वे तार होते हैं जो दशमलव पूर्णांक की तरह दिखते हैं, तो उनकी तुलना संख्याओं से की जाती है, और यदि Aइससे अधिक हैB , तो लूप निष्पादित होता है। तो मान लीजिए कि UNDER_NUCLEAR_ATTACKएक स्ट्रिंग-प्रकार का बूलियन नहीं है जो रिक्त या गैर-रिक्त है, लेकिन वास्तव में एक संख्यात्मक बूलियन है जो या तो 0(गलत) है या कुछ अन्य मूल्य (सच) है। उस मामले में, हम इस तरह परीक्षण लिखेंगे:

 if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...

-1

यदि कोई / तो परीक्षण का निर्माण करता है कि क्या कमांड की सूची से बाहर निकलने की स्थिति 0 है (क्योंकि 0 का अर्थ UNIX सम्मेलन द्वारा "सफलता" है), और यदि ऐसा है, तो एक या अधिक कमांड निष्पादित करता है।

संक्षेप में, आप शून्य का परीक्षा परिणाम लौटा रहे हैं।

http://www.tldp.org/LDP/abs/html/testconstructs.html


5
हां, लेकिन उस कारण के लिए नहीं जो आप सोचते हैं। यदि [केवल एक तर्क मिलता है ( ]बेशक, को छोड़कर ) यह स्थिति शून्य के साथ बाहर निकलता है यदि तर्क खाली नहीं है, तो गैर-शून्य यदि यह है। इसलिए, उदाहरण के लिए, [ 1 ]का एक निकास कोड भी लौटाएगा 0
केविन

-1

0 मान को लूप के लिए एक सत्य माना जाता है इसलिए लूप के लिए शर्त सही है और इसलिए यह अनंत लूप को दिखाता है। यह सच है अगर हम 0 को 1 के साथ बदलते हैं, क्योंकि किसी भी पूर्णांक के साथ हम इस शर्त के बीच लिखते हैं कि यह सच होगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.