지난 며칠 동안 시스템을 종료하고(Debian 테스트) bash 세션을 시작한 다음 위쪽 화살표 키를 누를 때마다 처음 사용할 때 기록 캐시를 지우라는 명령이 표시되는 것을 확인했습니다. history -c
. 어떻게 이런 일이 발생하는지 잘 모르겠지만 기록을 다시 지우고 위쪽 화살표를 눌러도 괜찮습니다. 하지만 다른 셸을 시작하면 작동하지 않습니다(재부팅하거나 종료할 때마다 또는 로깅할 때 더 적습니다). 밖으로).
모든 방법(수동 제거도 포함)을 시도했기 .bash_history
때문에 아이디어가 없습니다.
$ echo $SHELL
/bin/bash
$ /bin/bash --version
GNU bash, version 4.2.45(1)-release (i486-pc-linux-gnu)
$ echo $HISTFILE
/home/braiam/.bash_history
질문에 추가할 정보를 찾을 때 ls -l .bash_history
(바보처럼 보이지 않기 위해) 달려가 다음 질문을 찾았습니다.
$ ls -l .bash_history
-r--------. 1 braiam braiam 59372 Jul 26 20:18 .bash_history
그러나 달리기는 chmod +w .bash_history
하루를 구하지 못했습니다. 이제 어떻게 해서 이렇게 됐는지 궁금하네요...
파일을 삭제 한 후에 .bash_history
는 이제 기록이 없습니다. 단서를 찾기 위해 .bashrc를 확인했습니다.
cat .bashrc | grep -i hist
# don't put duplicate lines or lines starting with space in the history.
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
로그인하지 않은 (그놈 터미널) 쉘에서 Ash의 답변에 따라 다음을 수행하십시오.
braiam@bt:~$ echo abacaba; echo $$
abacaba
15372
braiam@bt:~$
그런 다음 또 다른 비로그인 셸을 시작합니다.
braiam@bt:~$ strace -o e -s 256 -p 15372
Process 15372 attached - interrupt to quit
첫 번째 쉘로 돌아가서 다음을 입력하십시오 history -a
.
braiam@bt:~$ echo abacaba; echo $$
abacaba
15372
braiam@bt:~$ history -a
braiam@bt:~$
strace가 있는 셸에는 아무것도 없습니다.
braiam@bt:~$ strace -oe -s 256 -p 15372 프로세스 15372 첨부 - 인터럽트 종료
나는 여기서 희망을 거의 포기할 뻔했기 때문에 strace 매뉴얼을 살펴보기로 결정하고 -o
결과를 파일에 덤프한다는 것을 알고 cat e
다음과 같이 반환했습니다.
cat e
read(0, "\33", 1) = 1
read(0, "[", 1) = 1
read(0, "A", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "history -w", 10) = 10
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "\33", 1) = 1
read(0, "[", 1) = 1
read(0, "A", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "\10a", 2) = 2
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "\r", 1) = 1
write(2, "\n", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGALRM, {0x80a1080, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGWINCH, {0x80a09e0, [], 0}, {0x80e9550, [], SA_RESTART}, 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80a0e30, [], 0}, 8) = 0
time(NULL) = 1378047084
stat64("/home/braiam/.bash_history", {st_mode=S_IFREG|0600, st_size=44, ...}) = 0
open("/home/braiam/.bash_history", O_WRONLY|O_APPEND|O_LARGEFILE) = 3
write(3, "history -w\nhistory -a\n", 22) = 22
close(3) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80a0e30, [], 0}, 8) = 0
time(NULL) = 1378047084
rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [], 8) = 0
ioctl(255, TIOCSPGRP, [15372]) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80a0e30, [], 0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
ioctl(0, TIOCGWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(0, TIOCSWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT QUIT ALRM TERM TSTP TTIN TTOU], [], 8) = 0
rt_sigaction(SIGINT, {0x80e9d00, [], 0}, {0x80a0e30, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGALRM, {0x80e9d00, [], 0}, {0x80a1080, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 0}, 8) = 0
rt_sigaction(SIGTSTP, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGWINCH, {0x80e9550, [], SA_RESTART}, {0x80a09e0, [], 0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "\33]0;braiam@bt: ~\7\33[01;31mbraiam@bt\33[00m:\33[01;34m~\33[00m$ ", 56) = 56
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, <unfinished ...>
따라서 이 진술에 따르면 아무런 문제가 없습니다. 그런 다음 아무런 기쁨도 없이 또 다른 비로그인 셸을 엽니다. 기록이 로드되지 않았습니다. A는 cat .bash_history
파일이 실제로 채워져 있지만 로그인이 아닌 쉘에서는 이를 허용하지 않음을 나타냅니다.
이제 둘 다 시도해 보았습니다.strace -o /tmp/e -s 512 bash
여기(글자 수 제한에 비해 너무 깁니다)strace -o /tmp/e -s 512 gnome-terminal
여기(둘 다pastebin.com에서 가져온 것입니다. 죄송합니다.)여기원래 설정을 사용하십시오(.bash_history에 대한 -w 권한 제외).
다음으로 Ctrl+Alt+F1로 로그인을 시도하고 로그인한 다음 위쪽 화살표를 누르고 손가락을 교차시키면 작동했습니다! 그러나 이것이 여전히 궁금합니다. 비로그인 쉘이 기록을 로드하지 않는 이유는 무엇입니까?
답변1
시도해 보셨나요 history -c && history -w
?
history -c
기록 함수 캐시를 지우고 history -w
.bash_history(없음)의 기록 함수 캐시에 명령을 씁니다.
또 다른 옵션은 bash 기록을 지우고 다음에 /dev/null > ~/.bash_history
연결하는 것 입니다 .~/.bash_history
/dev/null
ln -sf /dev/null ~/.bash_history
현재 셸 세션을 저장하지 않으려면 명령을 실행하여 history -r
기록 캐시를 초기 상태(세션 시작 전)로 재설정해야 합니다. 그런 다음 로그아웃하면 기록 캐시의 명령(셸 세션을 시작하기 전과 동일)이 기록됩니다..bash_history
답변2
이런 일이 발생할 수 있는 이유 중 하나는 셸이 정상적으로 종료되지 않았거나 셸이 계속 실행되는 동안 업데이트를 찾고 있기 때문입니다.
이 시나리오를 테스트하려면 실행 중인 셸 history -a
등에서 몇 가지 고유한 명령을 실행해 본 다음 새 셸을 시작해 보세요. echo abacaba
새 셸이 첫 번째 셸에서 업데이트를 받으면 기록 파일 쓰기 및 읽기가 제대로 작동합니다. 하지만 그래도 안되면 뭔가 문제가 있는 것이므로 제가 strace
직접 진단해보도록 하겠습니다.
또 확인해야 할 점은 HOME 변수가 변경되지 않았으며 passwd
사용자 파일에 설정된 것과 동일한 경로로 설정되어 있다는 것입니다.
strace를 사용하여 진단
- 껍질 속에,
echo abacaba; echo $$
- 다른 셸에서
strace -o e -s 256 -p $PID
= 첫 번째 셸$PID
의$$
출력 - 첫 번째 껍질에서는
history -a
- strace를 중지하고 어떻게 진행되는지 확인하세요
history -a
. open() 및 write() 호출이 있어야 합니다.
비대화형 쉘
이상하게도 비대화형 쉘은 쉘 기록을 얻지 못하지만 이는 여러 가지 이유로 설명될 수 있습니다. 더 많은 진단이 도움이 될 것입니다.
비대화형 쉘의 시작을 수정하여 strace를 삽입할 수 있는 경우 다시 Strace를 사용하여 도움을 받을 수 있습니다. 예를 들어, 다음은 strace를 사용하도록 수정된 셸 시작 명령을 보여줍니다.
bash /home/jack/bin/jacks_script
strace -f -o /tmp/e -s 512 bash /home/jack/bin/jacks_script
물론, 한 번에 둘 이상을 실행하면 /tmp/e
덮어쓰게 됩니다.
를 사용하십시오 grep open /tmp/e
. 쉘이 bash_history 파일을 로드한 경우 파일의 전체 경로가 표시되어야 합니다. 따라서 이 명령을 사용하면 (1) 기록 파일이 열리고 읽고 있는지, (2) 기록 파일에 대한 경로가 예상한 것과 같은 두 가지 검사가 가능합니다.
흔적이 없다
쉘에 history
옵션 세트( set -o history
bash용)가 있는지 확인하십시오.
불분명한 한 가지는 HISTFILE
쉘이 검사할 때입니다. 예를 들어, 에 설정하면 .bash_profile
쉘 기록 읽기에 영향을 미칠지 확실하지 않습니다. 왜냐하면 쉘이 시작된 후이지만 사용자에게 첫 번째 명령 프롬프트가 제공되기 전이기 때문입니다.
답변3
간단히 설정을 해제하면 $HISTFILE
(기록 파일의 경로 포함) 현재 세션에서 기록을 사용하는 기능에 영향을 미치지 않습니다.
unset HISTFILE
답변4
내가 한 일은 다음과 같이 HISTFILESIZE
파일에서 0으로 설정하는 것이 었습니다..bashrc
데브 슬론댓글에서 말했습니다.
[...]
HISTFILESIZE=0
[...]