เป็นการดีที่จะมีความคิดเห็นที่ไม่ถูกต้องล่าสุดเพื่อแก้ไข แต่หลังจากนั้นจะกลายเป็นขยะที่อาจทำให้เกิดความสับสน
วิธีการของฉันคือสองขั้นตอน: คำสั่งการจัดเก็บที่ล้มเหลวเมื่อพวกเขาทำและลบออกในภายหลัง
จัดเก็บคำสั่งที่ล้มเหลวเมื่อทำ:
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
คำอธิบาย:
เมื่อออกจาก Bash สำหรับแต่ละหมายเลขประวัติที่ไม่ซ้ำกันให้ลบรายการประวัติที่เกี่ยวข้อง
จากนั้นล้างFAILED_COMMANDSเพื่อไม่ลบคำสั่งที่รับหมายเลขประวัติที่สืบทอดมาจากคำสั่งที่ถูกลบไปแล้ว
หากคุณแน่ใจว่าFAILED_COMMANDSจะไม่ซ้ำซ้อนคุณสามารถทำซ้ำได้ง่าย
(เช่นเขียนfor i in $FAILED_COMMANDS) แต่ถ้าคุณคาดหวังที่จะไม่ได้เรียงลำดับจากมากที่สุดไปหาน้อยที่สุด (ในกรณีนี้ก็มักจะเป็น) แทนที่ด้วยuniqsort -rnu
หมายเลขประวัติFAILED_COMMANDSจะต้องไม่ซ้ำกันและเรียงลำดับจากมากที่สุดไปหาน้อยที่สุดเพราะเมื่อคุณลบรายการตัวเลขคำสั่งถัดไปจะเปลี่ยน - นั่นคือ เมื่อคุณออกhistory -d 2รายการที่ 3 กลายเป็นที่ 2 ที่ 4 กลายเป็นที่ 3 ฯลฯ
ด้วยเหตุนี้เมื่อใช้รหัสนี้คุณจึงไม่สามารถโทรด้วยตนเองในhistory -d <n>
กรณีที่nมีขนาดเล็กกว่าหรือเท่ากับจำนวนมากที่สุดที่จัดเก็บไว้FAILED_COMMANDS
และคาดว่ารหัสจะทำงานอย่างถูกต้อง
มันเป็นความคิดที่ดีอาจจะขอexit_handlerที่EXITแต่คุณยังสามารถโทรได้ตลอดเวลาก่อนหน้านี้