您说创意和涉及信号吗?好:
trap on_exit EXIT
trap on_usr1 USR1
on_exit() {
history -a
trap '' USR1
killall -u "$USER" -USR1 bash
}
on_usr1() {
history -n
}
塞进.bashrc
去。bash
当另一个进程退出时,它使用信号告诉每个进程检查新的历史记录条目。这非常糟糕,但确实有效。
它是如何工作的?
trap
为系统信号或Bash的内部事件之一设置信号处理程序。该EXIT
事件是外壳的任何控制终止,而USR1
为SIGUSR1
,我们占有一个毫无意义的信号。
每当外壳退出时,我们:
- 明确将所有历史记录追加到文件中。
- 禁用
SIGUSR1
处理程序,并使该外壳程序忽略该信号。
- 将信号
bash
从同一用户发送到所有正在运行的进程。
当SIGUSR1
到达时,我们:
- 将历史记录文件中的所有新条目加载到Shell的内存中历史记录列表中。
由于Bash处理信号的方式,您直到Enter下一次点击时才真正获得新的历史数据,因此在这方面并没有比history -n
放进去更好PROMPT_COMMAND
。但是,即使什么也没有发生,它确实可以节省不断读取文件的时间,并且在shell退出之前根本没有写入操作。
但是,这里仍然有几个问题。首先是默认响应SIGUSR1
是终止 shell。任何其他bash
进程(例如正在运行的Shell脚本)将被杀死。.bashrc
不是由非交互式外壳加载的。相反,将BASH_ENV
加载名为的文件:您可以在环境中全局设置该变量以指向具有以下内容的文件:
trap '' USR1
忽略其中的信号(可以解决问题)。
最后,尽管这样做可以满足您的要求,但是您得到的订购将有些不寻常。特别是,历史记录的各个部分在分别加载和保存时将以不同的顺序重复。这本质上是您要的内容,但是请注意,向上箭头的历史记录在这一点上变得不那么有用了。但是,历史记录替换之类的东西将被共享并很好地工作。