बैश स्क्रिप्ट लिखते समय && के बराबर क्या है?


31

मैं पहले से माफी मांगता हूं अगर यह एक डुप्लिकेट प्रश्न है। मैंने यहां पूछने से पहले खोज / जांच का प्रयास किया।

मैं इस तरह से वन-लाइनर्स लिखने में सहज हूं:

foocommand && foocommand2 && foocommand3

यह विचार कि मैं केवल बाद की आज्ञाओं को चलाना चाहता हूं यदि पिछले एक "सफल" था।

मैं कुछ लंबी स्क्रिप्ट लिख रहा हूं और यह एक-लाइनर संभव नहीं है क्योंकि यह कोड को हर किसी को भ्रमित करने का एक बड़ा ब्लॉक जैसा दिखता है।

मैं कमांड्स को स्पेस देना चाहता हूं और कमेंट्स लिखकर उन्हें स्क्रिप्ट में इनबेट करना चाहता हूं। मैं यह कैसे कर सकता हूं और अभी भी वहां && के बराबर है?


4
यह दोहराता है: &&इसका मतलब यह नहीं है कि बाद की कमान चलेगी यदि पिछले एक सफल रहा था। इसका अर्थ है कि कमांड चलेगा यदि कमांड सूची में सभी पिछले कमांडों का सामूहिक परिणाम सफलता है। आप यह जान सकते हैं, लेकिन भविष्य के पाठक गलत समझ सकते हैं।
कोजीरो

1
इसके अलावा सिर्फ एक नोट के रूप में, इस व्यवहार आपको लगता है कि वर्णन कर रहे हैं से आता है ||और &&(करने के लिए विरोध के रूप में |या &) लघु सर्किटिंग कहा जाता है। बाद के ऑपरेटरों के साथ उपयोग किए जाने वाले व्यवहार को उत्सुक मूल्यांकन कहा जाता है।
एंडीपरफेक्ट

7
@kojiro: मैं भेद नहीं देखता। a && b && cकेवल तभी चलेगा bजब aसफल होगा, इसलिए "यह केवल तभी चलता है cजब bसफल होता है" और "यह केवल तभी चलता है cयदि aऔर bदोनों सफल हों" समान कथन हैं: bजब तक aसफल नहीं हो सकते ।
बरबाद

1
@ruakh a || b && cअधिक स्पष्ट है।
कोजिरो

8
@ruakh नहीं, true || false && echo hiआउटपुट देगा hiविनिर्देश पढ़ता है, ऑपरेटर "और&" और "||" समान पूर्वता होगी और इसका मूल्यांकन बाईं सहयोगीता के साथ किया जाएगा।
कोजिरो

जवाबों:


23

आप इसे इस तरह से कर सकते हैं:

#!/bin/sh
ls -lh &&
    # This is a comment
    echo 'Wicked, it works!'

मुझे आशा है कि आपने जो कुछ पूछा था, मैं उसे ठीक से समझ गया हूँ।


धन्यवाद। यह वही है जो मैं करने की उम्मीद कर रहा था। और जरूरत पड़ने पर इसे वापस एक लाइनर में बदलना बहुत आसान हो जाता है।
माइक बी

माइक, चूंकि आप कोड स्वच्छता के बारे में चिंतित हैं, एक आम सम्मेलन पहले के नीचे श्रृंखला के 2-एन वर्गों को इंडेंट करना है।
jblaine

@jblaine मुझे यकीन नहीं है कि मैं समझ सकता हूं कि आपका क्या मतलब है। क्या आप कृपया विस्तार से बता सकते हैं?
माइक बी

माइक, Stackexchange मुझे मेरे जवाब को ठीक से प्रारूपित नहीं करने देगा, इसलिए यहाँ मेरा मतलब है: इंडेंट
jblaine

@jblaine अच्छी बात है, लाइनों को इंडेंट करने के लिए संपादित किया गया।
वोल्कर सेगेल

38

आप शेबंग लाइन को बदल सकते हैं

#!/bin/bash -e

किसी भी त्रुटि के बाद, स्क्रिप्ट बंद हो जाएगी।


1
दिलचस्प। में इसे याद रखूंगा। धन्यवाद।
माइक बी

जरूरत
पड़ने पर

@Silverrocker यह POSIX भी है ( bashपाठ्यक्रम के भाग को छोड़कर )। POSIX शेल उन विकल्पों का एक गुच्छा लेता है जो लागू होते हैं set। या ठीक इसके विपरीत? setस्क्रिप्ट के भीतर शेल कमांड लाइन विकल्प सेट करने का एक तरीका है।
कज़

7
दुर्भाग्य से, कई मानक उपयोगिताओं हैं जो सामान्य निकास-स्थिति सम्मेलनों का पालन नहीं करते हैं, इसलिए -eदुर्व्यवहार कर सकते हैं। उदाहरण के लिए, आप शायद नहीं चाहते कि आपकी स्क्रिप्ट हर बार जब आप diffदो गैर-समान फ़ाइलों को समाप्त करें। आप निश्चित रूप से इस तरह के आदेशों को जोड़कर || true(या शायद || [ $? = 1 ]) इसके चारों ओर काम कर सकते हैं, लेकिन ओपी एक "हर किसी" का उल्लेख करता है, जिसे इस स्क्रिप्ट को पढ़ना होगा, और कहा "हर किसी को" शायद इसका उपयोग करने की आदत नहीं होगी के साथ सामना -e
बरबाद

4
मैं -eशी-बैंग पर लगा रहता था , जब तक कि मेरी कंपनी के एक एडमिन ने मेरी स्क्रिप्ट को लॉन्च नहीं किया bash myscript.sh, इसलिए इसे नजरअंदाज कर दिया -e। अब मेरी सभी लिपियों set -eमें दूसरी पंक्ति है।
कार्लोस कैंपडरो

19

यदि आपको यह set -eविचार पसंद नहीं है, तो शायद आप तर्क को पलट सकते हैं।

foocommand || exit 1
foocommand2 || exit 2
foocommand3 || exit 3

अधिक उपयोगी रूप से, exitकिसी उपयोगी त्रुटि संदेश को प्रिंट करने के लिए किसी चीज़ से प्रतिस्थापित करें, फिर बाहर निकलें। एक फ़ंक्शन के अंदर, ज़ाहिर है, आप returnइसके बजाय चाहते हैं exit


11
या foocommand || exitके साथ बाहर निकलने के लिए foocommandकरता है, तो गैर शून्य के बाहर निकलने की स्थिति।
स्टीफन चेजलस 21

यह कैसे काम करता है? क्या यह C की तरह है - यदि बायाँ तर्क TRUE का मूल्यांकन करता है, तो कोई और तर्क जाँच नहीं किया जाता है?
वोरैक

हाँ य़ह सही हैं। यह लिस्प में एक आम मुहावरा है (और सामान्य रूप से कार्यात्मक भाषाएं, मुझे लगता है) और पर्ल में।
ट्रिपल

9

आप if else fiइसके बजाय ब्लॉक का उपयोग कर सकते हैं ।

if foocommand; then

  # some comments

  if foocommand2; then

    # more comments

    foocommand3
  fi
fi

यह थोड़ा अधिक पठनीय है।

वैकल्पिक रूप से आप बस \अपने बड़े 1 लाइनर को कई लाइनों में तोड़ने के लिए उपयोग कर सकते हैं

foocommand && \
  # some comment
  foocommand2 && \
    # more comment
    foocommand3

लेकिन निश्चित रूप से यह अप्रशिक्षित आंख को भ्रमित कर सकता है।


4
मुझे नहीं लगता कि \यह आवश्यक है।
सैमुअल एडविन वार्ड

तुम सही हो। आदत में शुमार।
मार्टन कैनावल

5

आप नेस्टेड ifस्टेटमेंट का उपयोग करने पर विचार कर सकते हैं । अन्य विकल्प यह है कि घुंघराले समूह का उपयोग करें{ true && echo hi; } || echo huh

अपडेट 1:

यहाँ newlines / टिप्पणियों के बिना एक उदाहरण है:

{ { false && echo "inner true"; } && { echo "inner true" && true; } || { echo "inner false" && false; } || echo "outter false"; }

@ स्टीफन अर्धविराम जोड़ने के लिए धन्यवाद। मैं अपने फोन का उपयोग उत्तर देने के लिए कर रहा हूं इसलिए मैं अपने उत्तरों की दोहरी जांच नहीं कर रहा हूं। :)
लिविंग रुकावट 21

दिलचस्प विचार। हाँ, मैंने बयानों के अनुसार नेस्टेड के बारे में सोचा था लेकिन अगर मैं बहुत सारे सामानों को एक साथ रख रहा हूं तो यह गड़बड़ हो सकता है।
मिक बी

4

कार्यों में आदेशों के प्रत्येक क्रम को विभाजित करें:

big_block_1() {
  # ...
}
big_block_2() {
  # ...
}
big_block_3() {
  # ...
}

big_block_1 && big_block_2 && big_block_3

0

मैं हमेशा एक "विफल" फ़ंक्शन लिखना पसंद करता हूं जो मुझे उस चीज़ को निर्दिष्ट करने देता है जो मैं तब कर रहा था जब विफलता हुई थी और फिर ||पैटर्न का उपयोग करें । निम्नलिखित की तरह:

function fail() {
  echo "Failure: ${@}"
  exit 1
}

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