为什么 bash_history 总是出现相同并且不使用非登录 shell 进行更新?

Bra*_*iam 6 command-line bash

最近几天我注意到,每当我关闭系统(Debian 测试)并启动 bash 会话,然后按向上箭头键时,我都会收到第一次使用 .bashrc 清除历史缓存时的命令history -c。我不确定这是怎么发生的,但即使我再次清除我的历史记录,然后按向上箭头,很好,但是如果我启动另一个 shell,它就不会(每当我重新启动、关闭或注销时更是如此) .

我已经尝试了所有方法(甚至.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
Run Code Online (Sandbox Code Playgroud)

在找资料添加问题的时候,跑了ls -l .bash_history(不是装傻)发现了问题:

$ ls -l .bash_history 
-r--------. 1 braiam braiam 59372 Jul 26 20:18 .bash_history
Run Code Online (Sandbox Code Playgroud)

但跑步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
Run Code Online (Sandbox Code Playgroud)

在 ash 的回答之后,在非登录(gnome-terminal)shell 中:

braiam@bt:~$ echo abacaba; echo $$
abacaba
15372
braiam@bt:~$ 
Run Code Online (Sandbox Code Playgroud)

然后启动另一个非登录shell:

braiam@bt:~$ strace -o e -s 256 -p 15372
Process 15372 attached - interrupt to quit
Run Code Online (Sandbox Code Playgroud)

回到第一个 shell,然后输入history -a

braiam@bt:~$ echo abacaba; echo $$
abacaba
15372
braiam@bt:~$ history -a
braiam@bt:~$ 
Run Code Online (Sandbox Code Playgroud)

在带有 strace 的 shell 中,什么都没有:

braiam@bt:~$ strace -oe -s 256 -p 15372
附加进程 15372 - 中断退出

到这里我几乎没有希望了,于是决定看一下strace手册,发现-o是把结果dump到一个文件里,所以cat ereturn这个:

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 ...>
Run Code Online (Sandbox Code Playgroud)

所以,根据这个,没有问题。然后,我打开另一个非登录外壳,并没有任何乐趣。历史记录未加载。Acat .bash_history显示该文件确实已填充,但非登录 shell 不接受它。

现在,我尝试了strace -o /tmp/e -s 512 bash 此处(字符限制太长)和strace -o /tmp/e -s 512 gnome-terminal 此处(均来自 pastebin.com,抱歉)。这里使用原始设置(减去 .bash_history 的 -w 权限)。

我接下来尝试登录,Ctrl + Alt + F1,登录,按下向上箭头,交叉手指,它奏效了!但是,这仍然让我感到疑惑,为什么非登录 shell 不加载历史记录?

Bra*_*iam 1

正如Drav Sloan在评论中所说,我最终所做的是HISTFILESIZE在文件中设置为 0 。.bashrc

[...]
HISTFILESIZE=0
[...]
Run Code Online (Sandbox Code Playgroud)