$ का मतलब? (डॉलर प्रश्न चिह्न) शेल स्क्रिप्ट में


जवाबों:


212

यह अंतिम निष्पादित कमांड की निकास स्थिति है।

उदाहरण के लिए कमांड trueहमेशा एक स्थिति देता है 0और falseहमेशा एक स्थिति देता है 1:

true
echo $? # echoes 0
false
echo $? # echoes 1

मैनुअल से: ( man bashआपके शेल में कॉल करके स्वीकार्य )

$?       सबसे हाल ही में निष्पादित अग्रभूमि पाइपलाइन की निकास स्थिति का विस्तार होता है।

कन्वेंशन का 0मतलब एक्जिट स्टेटस ऑफ सक्सेस और नॉन-जीरो रिटर्न स्टेटस का मतलब है फेल होना। विकिपीडिया पर निकास स्थितियों के बारे में अधिक जानें ।

इस तरह के अन्य विशेष चर हैं, जैसा कि आप इस ऑनलाइन मैनुअल पर देख सकते हैं: https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters


नोट $और ?दो अलग-अलग पैरामीटर हैं और $?बैश (1) मैनपेज में नहीं दिखाई देते हैं।
जोश हबदास

19

$?अंतिम निष्पादित कमांड का निकास मान लौटाता है। echo $?कंसोल पर प्रिंट करने वाले मान। शून्य का तात्पर्य एक सफल निष्पादन से है जबकि गैर-शून्य मान विफलता के विभिन्न कारणों के लिए मैप किए जाते हैं।

इसलिए जब स्क्रिप्टिंग; मैं निम्नलिखित सिंटैक्स का उपयोग करता हूं

if [ $? -eq 0 ]; then
 # do something
else
 # do something else
fi

बराबरी पर होना 0या न होना बराबर है 0

** अद्यतन टिप्पणी के आधार पर: आदर्श रूप से, आपको तुलना के लिए उपरोक्त कोड ब्लॉक का उपयोग नहीं करना चाहिए, @tripleee टिप्पणियों और स्पष्टीकरण को देखें।


15
नहीं, यह एक एंटीपैटर्न है। जो कुछ भी दिखता है, उसे वापस cmd; if [ $? -eq 0 ]; thenकरना चाहिए if cmd; then। बहुत उद्देश्य की if(और खोल में अन्य प्रवाह नियंत्रण बयान) एक आदेश चला और उसके बाहर निकलने की स्थिति की जांच करने के लिए है।
ट्रिपलए

if cmd;बहुत पठनीय नहीं हो सकता है कुछ शर्तें विशेष रूप से जब cmd किसी अन्य स्क्रिप्ट को संदर्भित करता है।
सौरभ एरियन

1
यह अब और भी गलत है। [ 1 ]और [ 0 ]दोनों सत्य हैं; [ऑपरेटर के बिना यह जांचता है कि क्या तर्क एक गैर-रिक्त स्ट्रिंग है।
ट्रिपल

2
मैं करने वाला हूं vendor/bin/drush status bootstrap | grep -q $(vendor/bin/drush php-eval 'if (function_exists("t")) echo t("Successful");') &> /dev/null;। अगर मुझे if [ ... ]इसे एक ही लाइन में रखना पड़े तो यह बहुत ही दुर्भाग्यपूर्ण होगा। मैं उस लाइन के आउटपुट को एक वैरिएबल में स्टोर करने की योजना बनाता हूं ताकि मैं if [ $drupal_installed -eq 0 ]बाद में कह सकूं।
थर्डेंडर

1
@ आर्थरेंडर इसका उचित समाधान है कि एक शेल फ़ंक्शन में जटिल परीक्षण को एनकैप्सुलेट किया जाए।
ट्रिपलए

12

इको $? - सबसे हाल ही में निष्पादित कमांड का EXIT STATUS देता है । यह बाहर निकलें स्थिति संभवत: शून्य जिसका अर्थ है के साथ एक नंबर होगा सफलता और किसी भी गैर शून्य मान का संकेत विफलता

? - यह एक विशेष पैरामीटर / बैश में परिवर्तनशील है।

$? - यह चर में संग्रहीत मूल्य देता है "?"।

BASH में कुछ इसी तरह के विशेष पैरामीटर 1,2, *, # हैं (आम तौर पर $ 1, $ 2, $ *, $ #, आदि के रूप में इको कमांड में देखा जाता है)।


8

इसमें कमांड का आखिरी स्टेटस कोड (एक्जिट वैल्यू) होता है।


5

न्यूनतम POSIX C निकास स्थिति उदाहरण

समझने के लिए $?, आपको पहले प्रक्रिया से बाहर निकलने की स्थिति की अवधारणा को समझना होगा जो कि POSIX द्वारा परिभाषित है । लिनक्स में:

  • जब कोई प्रक्रिया exitसिस्टम कॉल को कॉल करती है, तो कर्नेल सिस्टम कॉल (a) में दिए गए मान को संग्रहीत करता हैint ) को प्रक्रिया के मरने के बाद भी है।

    एग्जिट सिस्टम कॉल को exit()एएनएसआई सी फ़ंक्शन द्वारा बुलाया जाता है , और अप्रत्यक्ष रूप से जब आप करते returnहैं main

  • वह प्रक्रिया जिसे एक्ज़िटिंग चाइल्ड प्रोसेस (बैश) कहा जाता है, अक्सर fork+ के execसाथ, waitसिस्टम कॉल के साथ बच्चे की निकास स्थिति को पुनः प्राप्त कर सकता है।

बैश कोड पर विचार करें:

$ false
$ echo $?
1

C "समतुल्य" है:

false.c

#include <stdlib.h> /* exit */

int main(void) {
    exit(1);
}

bash.c

#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */

int main(void) {
    if (fork() == 0) {
        /* Call false. */
        execl("./false", "./false", (char *)NULL);
    }
    int status;
    /* Wait for a child to finish. */
    wait(&status);
    /* Status encodes multiple fields,
     * we need WEXITSTATUS to get the exit status:
     * http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
     **/
    printf("$? = %d\n", WEXITSTATUS(status));
}

संकलित करें और चलाएं:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o bash bash.c
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o false false.c
./bash

आउटपुट:

$? = 1

बैश में, जब आप एंट्री मारते हैं, तो एक कांटा + निष्पादित + प्रतीक्षा ऊपर की तरह होती है, और बैश तब $?फोर्क की प्रक्रिया की निकास स्थिति पर सेट होता है।

नोट: जैसे अंतर्निहित कमांड के लिए echo , एक प्रक्रिया की आवश्यकता नहीं होती है, और बैश केवल $?बाहरी प्रक्रिया को अनुकरण करने के लिए 0 पर सेट होता है।

मानक और प्रलेखन

POSIX 7 2.5.2 "विशेष पैरामीटर" http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :

? सबसे हालिया पाइपलाइन (देखें पाइपलाइनों) की दशमलव निकास स्थिति का विस्तार करता है।

man bash "विशेष पैरामीटर":

शेल कई मापदंडों को विशेष रूप से मानता है। इन मापदंडों को केवल संदर्भित किया जा सकता है; उन्हें असाइनमेंट की अनुमति नहीं है। [...]

? सबसे हाल ही में निष्पादित अग्रभूमि पाइपलाइन की निकास स्थिति का विस्तार होता है।

ANSI C और POSIX तब अनुशंसा करते हैं:

  • 0 कार्यक्रम सफल रहा था

  • अन्य मान: कार्यक्रम किसी भी तरह विफल रहा।

    सटीक मान विफलता के प्रकार को इंगित कर सकता है।

    ANSI C किसी भी वाऊस के अर्थ को परिभाषित नहीं करता है, और POSIX 125 से बड़ा मान निर्दिष्ट करता है: "POSIX" का अर्थ क्या है?

बैश के लिए बाहर निकलने की स्थिति का उपयोग करता है if

बैश में, हम अक्सर बयान $?को नियंत्रित करने के लिए बाहर निकलने की स्थिति का उपयोग करते हैं if:

if true; then
  :
fi

जहां trueएक प्रोग्राम है जो सिर्फ 0 देता है।

इसके बाद के संस्करण के बराबर है:

true
result=$?
if [ $result = 0 ]; then
  :
fi

और में:

if [ 1 = 1 ]; then
  :
fi

[एक अजीब नाम के साथ सिर्फ एक कार्यक्रम है (और बैश बिल्ट-इन है कि यह व्यवहार करता है), और 1 = 1 ]इसके तर्क, यह भी देखें: बैश में सिंगल और डबल स्क्वायर ब्रैकेट के बीच अंतर



3

3.4.2 विशेष पैरामीटर के तहत बैश मैनुअल देखें :

? - सबसे हाल ही में निष्पादित अग्रभूमि पाइपलाइन की निकास स्थिति का विस्तार।

यह खोजना थोड़ा कठिन है क्योंकि इसे सूचीबद्ध नहीं किया गया है $?(चर नाम "बस" है ?)। निकास स्थिति अनुभाग भी देखें;

खुश कोडिंग।


2

अंतिम निष्पादित यूनिक्स कमांड के परिणाम को आउटपुट करता है

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