如何获得不同选项卡之间的共享历史记录


19

我在/unix//a/1292/41729中使用了答案,以在各个bash终端之间启用实时共享历史记录。如以上答案中所述,这是通过添加以下内容来实现的:

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

# After each command, save and reload history
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

如果bash外壳是分开的(例如,使用打开bash终端),则此方法效果很好CTRL+ALT+T。但是,如果我使用tabs(从打开的终端“ CTRL + SHIFT + T”)而不是新窗口使用,则无法正常工作。是否可以在各个选项卡之间共享Bash历史记录?

更新:我注意到一种不寻常的行为:如果CTRL+C键入,则正确显示了在其他任何终端(无论是否为制表符)中键入的最后一个命令。就像CTRL + C强制刷新历史记录以便正确共享历史记录一样。

作为示例输出(T1表示端子1,T2表示端子2):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<up> (i.e. I press the up arrow)
ls -lah #i.e the last command in terminal 1 is shown rather than the last of terminal 2
^C (i.e. I press CTRL+C)
<up>
cd Documents #the last command issued in terminal 2 is correctly displayed

希望这可以提供任何提示!


您已将其添加到~.bashrc文件中?附带说明,导出这些变量是没有意义的。只是浪费环境空间。
geirha 2013年

@geirha是的,我已经添加到我的.bashrc文件中。感谢您对出口的评论。
lucacerone 2013年

Answers:


2

看起来您在尝试进行同步之前正在尝试访问另一个终端的历史记录。PROMPT_COMMAND在打印新提示之前(即您运行命令之后并且键入下一个命令之前)执行。因此,它不会立即在T1中发生;您必须导致显示新的提示。

要对此进行测试,请在您的步骤中尝试使用此变体(我<enter>在T1中添加了一个额外功能):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<enter>
<up> (i.e. I press the up arrow)

额外按Enter键,您会得到一个新的提示,该提示将运行PROMPT_COMMAND并同步您的历史记录,因此,我希望该向上箭头可以检索cd而不是ls所需的。不幸的是,我认为没有一种方法可以使同步在所有终端中即时发生而无需运行任何您想要的命令;有效地,这将要求您的所有登录会话始终保持连续同步其历史记录列表,这将浪费大量CPU和磁盘吞吐量。


您是对的,请按Enter,之后便会同步。即使浪费内存或CPU,我也可以强制执行同步?(如果同步太多,我可以始终禁用它,但是我想尝试一下)
lucacerone 2013年

1

我问了同样的问题,这是我想出的答案。

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

history() {
  _bash_history_sync
  builtin history "$@"
}

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

PROMPT_COMMAND=_bash_history_sync


在尝试之前先进行两个澄清:我应该删除其他hystory-选项吗?这在.bashrc中进行对吗?
lucacerone 2013年

不幸的是,它不起作用...
lucacerone 2013年

每次HISTFILESIZE更改时,它都会自动尝试截断现有历史记录文件。更改HISTSIZE对当前历史记录有类似的影响。作为参考,请参阅variables.cbash src中位于之前的注释sv_histsize
布赖恩·范登堡

1

将该行添加到您的.bashrc文件

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

trap 'history -r' USR1 
export PROMPT_COMMAND="history -a ; history -c; ps a | awk '/ bash$/ {system (\"kill -USR1 \" \$1)}'; $PROMPT_COMMAND"

注意:

最初,我做了一个测试托架,用killall将USR1信号发送到bash,后来我想使用一个唯一的shell名称,一个名为testshell的bash副本,以避免杀死我自己的可以运行的shell(例如cron进程),但是奇怪的是,工作。

Killall的选择性不够,我用一个脚本替换了它,该脚本仅杀死紧紧tty的bash进程(ps a仅报告绑定到tty的进程)

在进行测试时,请不要忘记重新启动会话以使用新的PROMPT_COMMAND,我看到很多以前的测试都存储在PROMPT_COMMAND中。


您不需要新用户和其他外壳程序,只需告诉您仅killall将信号发送给同一用户的进程即可,并带有附加-u参数, e.g. -u $(whoami)`。
菲利普·温德勒

我认为csh的语法是错误的... @PhilippWendler您能详细说明一下吗?
lucacerone

问题是关于bash的,所以我使用了bash语法。我不知道csh。对于bash,killall -q -USR1 -u $(whoami) bash将USR1信号发送到当前用户的所有bash进程。
Philipp Wendler 2013年

@Philipp ty btw我没有测试专用的shell解决方案,这是为了解决cron bash脚本将运行的情况。
伊曼纽尔

我改写的@LucaCerone似乎有用
Emmanuel

0

尝试创建精心制作的bash提示时,我在Yakuake中有相同的奇怪行为,该提示将显示另一个登录的数量。标签的数量没有增加。我的解决方法是告诉Yakuake bash在每个新选项卡中再次运行,本质上是从bash开始bash。它开始正常工作。也许对您也有帮助。我的盲目猜测是控制台的GUI本身会加载bash配置,然后将其提供给bash实例。也许是能够与他们玩弄。


我试图用bash加载bash,但没有成功:(
lucacerone 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.