BASH इतिहास में केवल सफल कमांड रखें


20

कभी-कभी मैं एक कमांड के सिंटैक्स को गलत समझता हूं:

# mysql -d test
mysql: unknown option '-d'
# echo $?
2

मैं फिर से कोशिश करता हूं और इसे ठीक करता हूं:

# mysql --database test
Welcome to the MySQL monitor.
mysql >
...

इतिहास दर्ज करने के लिए मैं 0 से भिन्न त्रुटि कोड वाली पहली कमांड को कैसे रोकूं?

जवाबों:


20

मुझे नहीं लगता कि आप वास्तव में ऐसा चाहते हैं। मेरा सामान्य वर्कफ़्लो इस प्रकार है:

  • एक कमांड टाइप करें
  • चलाओ
  • इसे फेल होने की सूचना दें
  • UP कुंजी दबाएं
  • कमांड को संपादित करें
  • इसे फिर से चलाएं

अब, यदि विफल आदेश को इतिहास में सहेजा नहीं गया था, तो मैं इसे आसानी से ठीक करने और फिर से चलाने के लिए वापस नहीं पा सकता था।


3
मुझे लगता है कि एक बेहतर डिजाइन एक सत्र इतिहास और एक स्थायी इतिहास होगा। धन्यवाद!
एडम मटन

जब आप टर्मिनल से बाहर निकलते हैं तो इतिहास बच जाता है। इसलिए जब आप इस टर्मिनल सत्र में टाइप किए गए आदेशों पर वापस जा सकते हैं तो यह वास्तव में टर्मिनल से बाहर निकलने पर बैश इतिहास के लिए सहेजे जाते हैं।
करने के लिए

11

एक ही रास्ता मैं के बारे में सोच सकते हैं यह करने के लिए उपयोग करने के लिए किया जाएगा history -dमें $PROMPT_COMMAND। इस या किसी भी दृष्टिकोण के साथ समस्या यह है कि यह बताना असंभव है कि क्या कोई कमांड त्रुटि के साथ बाहर निकली है या गैर-शून्य निकास कोड के साथ सफलतापूर्वक पूर्ण हुई है।

$ grep non_existent_string from_file_that_exists
$ echo $?
1

4

इसे सही करने के लिए अंतिम गलत टिप्पणी करना अच्छा है, लेकिन इसके तुरंत बाद, यह संभावित रूप से भ्रमित करने वाला कचरा बन जाता है।

मेरा दृष्टिकोण दो-चरणीय है: उन आदेशों को संग्रहीत करें जो वे करते समय विफल हो जाते हैं, और कुछ समय बाद उन्हें हटा देते हैं।

जब वे करते हैं तो आदेशों को संग्रहीत करें:

error_handler() {
    FAILED_COMMANDS="$(history | tail -1l | cut -c -5) $FAILED_COMMANDS"
}

trap error_handler ERR

trap command signalsनिष्पादित commandजब एक signals"उठाया" है।

$(command), निष्पादित करता है commandऔर इसके उत्पादन को पकड़ता है।

जब कमांड विफल हो जाता है, तो कोड का यह स्निपेट इतिहास में सहेजे गए अंतिम कमांड के इतिहास की संख्या को कैप्चर करता है , और इसे भविष्य के विलोपन के लिए चर में संग्रहीत करता है।

सरल, लेकिन गलत तरीके से काम करता है HISTCONTROLऔर HISTIGNORE- जब किसी एक चर के कारण कमांड को इतिहास में सहेजा नहीं जाता है, तो इतिहास में सहेजे गए अंतिम कमांड की इतिहास संख्या पिछली कमांड की एक है; इसलिए, यदि गलत कमांड को इतिहास में सहेजा नहीं गया है, तो पिछली कमांड डिलीट होने वाली है।

थोड़ा और अधिक जटिल संस्करण, जो उस स्थिति में सही ढंग से काम करता है:

debug_handler() {
    LAST_COMMAND=$BASH_COMMAND;
}

error_handler() {
    local LAST_HISTORY_ENTRY=$(history | tail -1l)

    # if last command is in history (HISTCONTROL, HISTIGNORE)...
    if [ "$LAST_COMMAND" == "$(cut -d ' ' -f 2- <<< $LAST_HISTORY_ENTRY)" ]
    then
        # ...prepend it's history number into FAILED_COMMANDS,
        # marking the command for deletion.
        FAILED_COMMANDS="$(cut -d ' ' -f 1 <<< $LAST_HISTORY_ENTRY) $FAILED_COMMANDS"
    fi
}

trap error_handler ERR
trap debug_handler DEBUG

कुछ समय बाद संग्रहीत आदेश निकालें:

exit_handler() {
    for i in $(echo $FAILED_COMMANDS | tr ' ' '\n' | uniq)
    do
        history -d $i
    done
    FAILED_COMMANDS=
}

trap exit_handler EXIT

स्पष्टीकरण:

बैश से बाहर निकलते समय, प्रत्येक अद्वितीय इतिहास संख्या के लिए संबंधित इतिहास प्रविष्टि को हटा दें,
फिर FAILED_COMMANDSपहले से हटाए गए आदेशों से विरासत में मिली संख्याओं को हटाने के लिए स्पष्ट न करें।

यदि आप सुनिश्चित हैं कि FAILED_COMMANDSडुप्लिकेट से मुक्त होंगे, तो आप इस पर सरल पुनरावृति कर सकते हैं
(यानी। लिखिए for i in $FAILED_COMMANDS)। यदि, हालांकि, आप यह अपेक्षा करते हैं कि इसे सबसे बड़े से लेकर सबसे छोटे (इस मामले में यह हमेशा होता है) में क्रमबद्ध न किया जाए, से प्रतिस्थापित uniqकरें sort -rnu

इतिहास संख्याएँ FAILED_COMMANDSअद्वितीय होनी चाहिए और सबसे बड़ी से छोटी से छोटी क्रमबद्ध होनी चाहिए, क्योंकि जब आप प्रविष्टि को हटाते हैं, तो अगले आदेशों की संख्याएँ स्थानांतरित हो जाती हैं - अर्थात। जब आप जारी करते हैं history -d 2, तो 3 की प्रविष्टि 2 वें हो जाती है, 4 जी 3 हो जाती है, आदि।

इस कारण, इस कोड का उपयोग करते समय, आप मैन्युअल रूप से कॉल नहीं कर सकते हैं, history -d <n>
जहां nसबसे छोटी संख्या के बराबर या इसके बराबर संग्रहीत किया जाता हैFAILED_COMMANDS
और कोड को ठीक से काम करने की उम्मीद करता है।

यह शायद हुक करने अच्छा विचार है exit_handlerपर EXITहै, लेकिन आप भी इसे कभी भी पहले कह सकते हैं।

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