Bash 대화형 셸에 명령을 입력할 때 철자 오류가 발생하는 것은 드문 일이 아닙니다. 나는 잘못된 명령으로 인해 bash 기록이 오염되어 나중에 실수로 다시 실행되는 일이 없도록 bash 기록의 오타를 수정할 수 있기를 원합니다. 특히 마지막 명령을 편집하고 싶습니다.
가지다상당히 ㅏ 숫자 ~의 질문어떻게 물어보세요예방하다실수로 bash 기록을 편집했습니다. 나는 그 반대를 원한다: 나는 원한다분명히기록을 편집합니다.
참조 질문의 일부 설명을 바탕으로 다음을 시도했습니다.
$ echo foo
Up다음과 같이 변경하려면 누르세요 .
$ echo foobar
누르지 Down만 아무 작업도 수행되지 않습니다. 그런 다음 누르면 Enter수정된 명령이 실행되고 둘 다 유지됩니다.
echo foo
echo foobar
내 역사에.
기록 항목을 수동으로 삭제할 수 있다는 것을 알고 있지만 history -d
편리하게 사용할 수 있는 좋은 방법은 고안하지 못했습니다. 마지막 기록 항목을 무조건 삭제하는 쉘 함수를 만들고 싶지 않습니다. 왜냐하면 Up마지막 항목을 로드하여 수정할 수 있기를 원하기 때문입니다. 수정한 다음 마지막에서 두 번째 기록 항목을 삭제할 수 있지만 이는 투박한 느낌이 들며 나중에 추가 단계를 수행해야 한다는 것을 기억하거나 이 단계의 실행을 일시적으로 일시 중지해야 한다는 것을 기억해야 하기 때문에 장기 실행 명령의 경우 특히 짜증납니다. 계속하다.
내가 원하는 것은:
이상적으로 내가 할 수 있는 작업은 를 누르고 Up이전 명령을 수정한 다음 특수 키 바인딩을 누르거나 명령줄에 마법 플래그를 추가하여 실행 시 기록 항목을 대체하는 것입니다.
실행 시 기록 항목을 덮어쓰는 기록에서 명령을 검색하고 편집하기 위해 다른 키 시퀀스를 누르는 것도 허용됩니다(Ctrl+R과 유사).
ㅏ강한마지막에서 두 번째 기록 항목을 삭제하는 셸 기능은 허용되지만 이상적이지는 않습니다.
나는 다른 사람들도 실수를 했을 것이고, 이러한 명령이 그들의 역사를 더럽힐 때 똑같이 짜증을 냈을 것이라고 생각합니다. 다른 사람들은 무엇을 하나요?
답변1
옵션 #1 - 수동
~/.bash_history
편집기에서 파일을 열고 파일 vim
에 원하는 대로 변경한 후 저장하면 됩니다.
$ vim ~/.bash_history
편집하기 전에 현재 터미널 기록도 이 파일에 커밋되어 있는지 확인하세요.
$ history -a
기록 파일은 이 환경 변수가 가리키는 위치에 있습니다.
$ echo $HISTFILE
/Users/user1/.bash_history
옵션 #2 - HSTR
~/.bash_history
보다 체계적인 방식으로 파일을 관리하는 데 사용할 수 있는 HSTR이라는 CLI 도구가 있습니다 . 이것HSTR 메인 웹사이트사용방법과 동영상입니다.
또한 다음과 같은 소개도 언급합니다.
HSTR은 또한 명령 기록을 관리하거나(예: 오래되었거나 중요한 정보가 포함된 명령 삭제) 즐겨찾는 명령을 북마크에 추가할 수 있습니다.
자세한 내용은 전체 설명서를 참조하세요.HSTR 파일.
인용하다
답변2
고속 철도매력적으로 보이지만 나에게는 너무 무거워 보였습니다.
대신, 나는 나만의 bash 함수를 작성했습니다:
# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
# historysub SEARCH [REPLACEMENT]
# historysub -d SEARCH
#
# REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
# -d removes the last command matching SEARCH from the history without
# executing a new command.
historysub()
{
local delete=0
local usage=0
local OPTIND=1
while getopts ":hd" option; do
case "${option}" in
d) delete=1 ;;
h) usage=1 ;;
?) usage=2 ;;
esac
done
shift $((OPTIND - 1))
local search="${1-}"
local replacement="${2-}"
usage_text=
usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]\n"
usage_text+=" ${FUNCNAME[0]} -d SEARCH\n"
if (( usage )); then
echo -e "${usage_text}"
return $(( usage - 1 ))
fi
if [[ -z "${search}" ]]; then
echo -e "${usage_text}" >&2
return 1
fi
# RE to parse the `history` output.
local hist_re='^[ \t]*([0-9]+)[ \t]+(.+)$'
local hist_full
hist_full=$(HISTTIMEFORMAT="" history)
# We don't want the search string to accidentally match against history
# numbers, so split the `history` output so that we can search against just
# the commands.
local hist_nums hist_cmds
hist_nums=$(sed -E "s/${hist_re}/\1/" <<< "${hist_full}")
hist_cmds=$(sed -E "s/${hist_re}/\2/" <<< "${hist_full}")
# Find the last matching history entry (excluding ourself).
local matches last_match
matches=$(grep -nF -- "${search}" <<< "${hist_cmds}")
last_match=$(grep -vF -- "${FUNCNAME[0]}" <<< "${matches}" | tail -n 1)
if [[ -z "${last_match}" ]]; then
echo "${FUNCNAME[0]}: \"${search}\" not found." >&2
return 1
fi
# RE to parse the `grep -n` output.
local line_re='^([0-9]+):[ \t]*(.+)$'
# Note that the line number and the history number might not be the same, so
# we need to retrieve the original history number.
local line_num hist_cmd hist_num
line_num=$(sed -E "s/${line_re}/\1/" <<< "${last_match}")
hist_cmd=$(sed -E "s/${line_re}/\2/" <<< "${last_match}")
hist_num=$(tail -n +${line_num} <<< "${hist_nums}" | head -n 1)
history -d "${hist_num}"
if (( delete )); then
echo "Removed: ${hist_cmd}"
return 0
fi
local cmd="${hist_cmd/${search}/${replacement}}"
echo "${cmd}"
# Add the new command to the history.
history -s -- "${cmd}"
eval -- "${cmd}"
}
이제 명령을 실행 historysub TYPO CORRECTION
하고 수정하여 명령을 다시 실행할 수 있습니다. 이전 명령을 대화식으로 편집할 수 있는 것만큼 좋지는 않지만 내 요구 사항에는 충분하다고 생각합니다.