इसे सही करने के लिए अंतिम गलत टिप्पणी करना अच्छा है, लेकिन इसके तुरंत बाद, यह संभावित रूप से भ्रमित करने वाला कचरा बन जाता है।
मेरा दृष्टिकोण दो-चरणीय है: उन आदेशों को संग्रहीत करें जो वे करते समय विफल हो जाते हैं, और कुछ समय बाद उन्हें हटा देते हैं।
जब वे करते हैं तो आदेशों को संग्रहीत करें:
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
है, लेकिन आप भी इसे कभी भी पहले कह सकते हैं।