व्यक्तिगत कमांड के लिए सेट-ई को कैसे निष्क्रिय करें?


36

जब कोई भी कमांड नॉन-जीरो एग्जिट कोड देता है तो सेट-कमांड कमांड बैश स्क्रिप्ट को तुरंत विफल कर देता है।

  1. क्या स्क्रिप्ट के भीतर एक व्यक्तिगत आदेश के लिए इस व्यवहार को अक्षम करने का एक आसान और सुरुचिपूर्ण तरीका है?

  2. बैश संदर्भ नियमावली ( http://www.gnu.org/software/bash/manual/bashref.html ) में यह कार्यक्षमता किन स्थानों पर प्रलेखित है ?

जवाबों:


29
  1. कुछ इस तरह:

    #!/usr/bin/env bash
    
    set -e
    echo hi
    
    # disable exitting on error temporarily
    set +e
    aoeuidhtn
    echo next line
    
    # bring it back
    set -e
    ao
    
    echo next line
    

    चलाएँ:

    $ ./test.sh
    hi
    ./test.sh: line 7: aoeuidhtn: command not found
    next line
    ./test.sh: line 11: ao: command not found
    
  2. यह setबिलिन मदद में वर्णित है :

    $ type set
    set is a shell builtin
    $ help set
    (...)
    Using + rather than - causes these flags to be turned off.
    

वही यहाँ प्रलेखित है: https://www.gnu.org/software/bash/manual/bashref.html#The-Set-Builtin


धन्यवाद! मुझे एक और संभावना मिली: #! / Bin / bash set -e # Uncomment अगली पंक्ति सेट -ई प्रभाव देखने के लिए: #blubb if blubb; तब गूंज "कमांड ब्लब सक्सेसफुल था।" और प्रतिध्वनि "कमांड ब्लब विफल हुआ। बाहर निकलें कोड: $?" Fi इको सामान्य स्क्रिप्ट से बाहर निकलें
Gustave

22

त्रुटि पर जमानत को रद्द करने का एक विकल्प एक सफलता के लिए मजबूर करना होगा चाहे वह कोई भी हो। आप ऐसा कुछ कर सकते हैं:

cmd_to_run || true

यह 0 (सही) लौटेगा, इसलिए सेट-ट्रिगर चालू नहीं होना चाहिए


3
faulty_cmd || :इसके लिए एक और लोकप्रिय मुहावरा है। ( :एक कमांड पर्यायवाची है true)।
ulidtko

3
@ulidtko - दिलचस्प। मुझे खरगोश की मांद नीचे के नेतृत्व में इस लगाने के लिए stackoverflow.com/questions/3224878/... सच बनाम पर इतिहास पाने के लिए:
एर्नी

12

यदि आप रिटर्न / त्रुटि कोड (फ़ंक्शन या कांटा) को पकड़ने की कोशिश कर रहे हैं, तो यह काम करता है:

function xyz {
    return 2
}

xyz && RC=$? || RC=$?

8

यदि "बाहर निकलें तुरंत शेल विकल्प" लागू होता है या अनदेखा किया जाता है, तो निष्पादित कमांड के संदर्भ पर निर्भर करता है (देखें सेट बेसिन पर बैश संदर्भ मैनुअल अनुभाग - अरकाडिज़ डेराबसीक के लिए धन्यवाद)।

विशेष रूप से, यदि एक आदेश एक बयान में परीक्षण का हिस्सा है, तो विकल्प की अनदेखी की जाती है। इसलिए इस तरह के एक बयान का उपयोग करके एक "तुरंत बाहर संदर्भ" के भीतर एक आदेश को निष्पादित करना और उसकी सफलता या विफलता की जांच करना संभव है:

#!/bin/bash

set -e

# Uncomment next line to see set -e effect:
#blubb

if blubb; then
  echo "Command blubb was succesful."
else 
  echo "Command blubb failed. Exit code: $?"
fi
echo "Script exited normally."

"तब" कथन को छोड़ना और कम लाइनों का उपयोग करना संभव है:

if blubb; then :;
else echo "Command blubb failed. Exit code: $?"; fi

2

एक और दृष्टिकोण, जो मुझे काफी सीधा लगता है (और setइसके अलावा अन्य विकल्पों पर लागू होता है -e):

$-सेटिंग्स को पुनर्स्थापित करने के लिए उपयोग करें ।

उदाहरण के लिए:

oldopt=$-
set +e
# now '-e' is definitely disabled.
# do some stuff...

# Restore things back to how they were
set -$oldopt

हालांकि -eविशेष रूप से, दूसरों ने जिन विकल्पों का उल्लेख किया है ( || trueया "अंदर डाल दिया if") अधिक मुहावरेदार हो सकता है।


0

मेरा वास्तव में हाल ही में एक समान प्रश्न था (हालांकि मैंने पोस्ट नहीं किया था, मैं इसके चारों ओर हो गया था), और, जो मैं देख सकता हूं, उससे ऐसा लगता है कि कमांड के पहले सेट + ई का उपयोग करना और उसके बाद सेट-एल सबसे काम करता है। यहां एक उदाहरण है, कमांड की प्रतिक्रिया को हथियाने और त्रुटि को दूर फेंकने नहीं देना।

#!/bin/sh

args=""
for argcol in $*
do
    args="${args} ${argcol}"
done
fortunevar=""
fortfail=""
{
    set +e
    fortunevar=`fortune $args`
    fortfail=$?
    set -e
} &> /dev/null
if [ $fortfail == 0 ]
then
    echo ${fortunevar}
    say ${fortunevar}
else
    echo misfortune: an illegal option was detected!
    echo misfortune: usage: misfortune [-afilosw] [-m pattern][ [#%] file/directory/all]
fi

यह 'भाग्य' के उत्पादन को पकड़ता है, इसकी निकास स्थिति और गूँज की जाँच करता है और कहता है। मुझे लगता है कि यह वही है जो आप के लिए पूछ रहे थे, या कम से कम कुछ इसी तरह का? वैसे भी, उम्मीद है कि यह मदद करता है।


स्पष्ट करने के लिए, घुंघराले पैरेंटिकल में बिट को / dev / null में रीडायरेक्ट किया जा रहा है, जो आपके बाद है, मेरा मानना ​​है। यह प्रोग्राम को बाहर निकाले बिना कमांड को अलग नहीं करता है और इसकी त्रुटि स्थिति की जांच करता है।
Addison Crump

0

अगर कुछ अस्थायी रूप से बदलना चाहते हैं, तो मुझे सब्सक्रिप्शन शुरू करना पसंद है। नीचे दिए गए आदेश से पता चलता है कि पहले bad_command को नजरअंदाज किया जाता है और दूसरा गर्भपात निष्पादन।

bash -c 'set -e ;\
( set +e; bad_command ; echo still here ) ;\
echo even here ; \
bad_command ; \
echo but not here;'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.