答案1
你说创意和涉及信号?好的:
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
事件是 shell 的任何受控终止,而USR1
is 是SIGUSR1
我们占用的无意义信号。
每当 shell 退出时,我们:
- 将所有历史记录显式附加到文件中。
- 禁用
SIGUSR1
处理程序并创建此 shell忽略信号。 - 将信号发送到
bash
同一用户的所有正在运行的进程。
当 aSIGUSR1
到达时,我们:
- 将历史文件中的所有新条目加载到 shell 的内存历史列表中。
由于 Bash 处理信号的方式,在Enter下次点击之前,您实际上不会获得新的历史数据,因此这在这方面并没有比输入更好history -n
进入PROMPT_COMMAND
。不过,当没有发生任何事情时,它确实会不断地读取文件,并且在 shell 退出之前根本不会进行写入。
然而,这里仍然存在一些问题。第一个是默认响应SIGUSR1
是终止贝壳。任何其他bash
进程(例如运行 shell 脚本)都将被终止。.bashrc
不由非交互式 shell 加载。反而,一个名为的文件BASH_ENV
加载了:您可以在全局环境中设置该变量以指向文件:
trap '' USR1
其中忽略其中的信号(这解决了问题)。
最后,虽然这满足了您的要求,但您得到的顺序会有点不寻常。特别是,当历史记录被单独加载和保存时,它们将以不同的顺序重复。这本质上是您所要求的固有内容,但请注意,此时向上箭头历史记录的用处要小得多。历史换人不过,类似的内容将被共享并且运行良好。