Oli*_*Oli 633 bash command-history
我一直有不止一个终端打开。从两个到十个,做各种各样的点点滴滴。现在假设我重新启动并打开另一组终端。有些人记得某些事情,有些人忘记了。
我想要一段历史:
ls在一个终端,切换到另一个已经运行的终端,然后按下,ls显示)我能做些什么让 bash 更像那样工作?
小智 401
将以下内容添加到您的~/.bashrc:
# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend
# After each command, append to the history file and reread it
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Run Code Online (Sandbox Code Playgroud)
小智 279
所以,这就是我所有与历史相关的.bashrc事情:
export HISTCONTROL=ignoredups:erasedups # no duplicate entries
export HISTSIZE=100000 # big big history
export HISTFILESIZE=100000 # big big history
shopt -s histappend # append to history, don't overwrite it
# Save and reload the history after each command finishes
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
Run Code Online (Sandbox Code Playgroud)
在 Mac OS X 10.5 上用 bash 3.2.17 测试,在 10.6 上用 bash 4.1.7 测试。
les*_*ana 131
这是我对 Bash 会话历史共享的尝试。这将启用 bash 会话之间的历史共享,历史计数器不会混淆,并且历史扩展!number可以正常工作(有一些限制)。
在 Ubuntu 10.04 LTS (Lucid Lynx) 下使用 Bash 版本 4.1.5。
HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups
_bash_history_sync() {
builtin history -a #1
HISTFILESIZE=$HISTSIZE #2
builtin history -c #3
builtin history -r #4
}
history() { #5
_bash_history_sync
builtin history "$@"
}
PROMPT_COMMAND=_bash_history_sync
Run Code Online (Sandbox Code Playgroud)
将刚刚输入的行附加到$HISTFILE(默认为.bash_history)。这将导致$HISTFILE增长一行。
将特殊变量设置$HISTFILESIZE为某个值将导致 Bash通过删除最旧的条目来截断$HISTFILE不超过$HISTFILESIZE行的长度。
清除正在运行的会话的历史记录。这将减少历史计数器的数量$HISTSIZE。
读取 的内容$HISTFILE并将它们插入到当前正在运行的会话历史记录中。这将使历史计数器增加 中的行数$HISTFILE。请注意, 的行数$HISTFILE不一定是$HISTFILESIZE。
该history()函数会覆盖内置历史记录,以确保在显示历史记录之前进行同步。这对于按数字进行历史扩展是必要的(稍后会详细介绍)。
步骤 1 确保来自当前运行会话的命令被写入全局历史文件。
步骤 4 确保来自其他会话的命令被读入当前会话历史记录。
因为第 4 步会增加历史计数器,我们需要以某种方式减少计数器。这是在步骤 3 中完成的。
在步骤 3 中,历史计数器减少了$HISTSIZE。在步骤 4 中,历史计数器由 中的行数增加$HISTFILE。在第 2 步中,我们确保 的行数$HISTFILE完全相同$HISTSIZE(这意味着$HISTFILESIZE必须与 相同$HISTSIZE)。
使用数字历史扩展时,您应该始终在使用前立即查找数字。这意味着在查找号码和使用号码之间不会显示 bash 提示。这通常意味着没有输入和没有 ctrl+c。
通常,一旦您有多个 Bash 会话,就无法保证按数字展开的历史记录将在两个 Bash 提示显示之间保留其值。因为在PROMPT_COMMAND执行时,所有其他 Bash 会话的历史记录都集成在当前会话的历史记录中。如果任何其他 bash 会话有新命令,则当前会话的历史记录编号将不同。
我觉得这个限制是合理的。反正我每次都得查这个数字,因为我记不起任意的历史数字。
通常我使用这样的数字扩展历史
$ history | grep something #note number
$ !number
Run Code Online (Sandbox Code Playgroud)
我建议使用以下 Bash 选项。
## reedit a history substitution line if it failed
shopt -s histreedit
## edit a recalled history line before executing
shopt -s histverify
Run Code Online (Sandbox Code Playgroud)
运行通过管道传输到任何内容的历史命令将导致该命令在历史记录中列出两次。例如:
$ history | head
$ history | tail
$ history | grep foo
$ history | true
$ history | false
Run Code Online (Sandbox Code Playgroud)
都将被列入历史两次。我不知道为什么。
修改函数_bash_history_sync(),使其不会每次都执行。例如,它不应CTRL+C在提示后执行。CTRL+C当我决定不想执行该行时,我经常使用丢弃长命令行。有时我必须使用CTRL+C来停止 Bash 完成脚本。
当前会话中的命令应该始终是当前会话历史中的最新命令。这也将产生副作用,即给定的历史编号保留其来自该会话的历史条目的值。
Mac*_*tka 52
我不知道以任何方式使用bash. 但它是zsh.
我个人更喜欢zsh,bash所以我建议尝试一下。
这是我.zshrc处理历史的部分:
SAVEHIST=10000 # Number of entries
HISTSIZE=10000
HISTFILE=~/.zsh/history # File
setopt APPEND_HISTORY # Don't erase history
setopt EXTENDED_HISTORY # Add additional data to history like timestamp
setopt INC_APPEND_HISTORY # Add immediately
setopt HIST_FIND_NO_DUPS # Don't show duplicates in search
setopt HIST_IGNORE_SPACE # Don't preserve spaces. You may want to turn it off
setopt NO_HIST_BEEP # Don't beep
setopt SHARE_HISTORY # Share history between session/terminals
Run Code Online (Sandbox Code Playgroud)
Chr*_*own 18
为此,您需要在您的 中添加两行~/.bashrc:
shopt -s histappend
PROMPT_COMMAND="history -a;history -c;history -r;$PROMPT_COMMAND"
Run Code Online (Sandbox Code Playgroud)
来自man bash:
如果启用了 histappend shell 选项(请参阅下面 SHELL BUILTIN COMMANDS 下的 shopt 说明),这些行将附加到历史文件中,否则历史文件将被覆盖。
小智 13
您可以编辑 BASH 提示符以运行 Muerr 建议的“history -a”和“history -r”:
savePS1=$PS1
Run Code Online (Sandbox Code Playgroud)
(万一你搞砸了,这几乎是可以保证的)
PS1=$savePS1`history -a;history -r`
Run Code Online (Sandbox Code Playgroud)
(请注意,这些是反引号;它们将在每个提示上运行 history -a 和 history -r。由于它们不输出任何文本,因此您的提示将保持不变。
按照您想要的方式设置 PS1 变量后,将其永久设置在您的 ~/.bashrc 文件中。
如果您想在测试时返回原始提示,请执行以下操作:
PS1=$savePS1
Run Code Online (Sandbox Code Playgroud)
我已经对此进行了基本测试以确保它可以正常工作,但无法说明history -a;history -r在每个提示下运行的任何副作用。
pts*_*pts 11
如果您需要 bash 或 zsh 历史同步解决方案也可以解决以下问题,请在http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.html 上查看
问题如下:我有两个 shell 窗口 A 和 B。在 shell 窗口 A 中,我在 shell 窗口 B 中运行sleep 9999, 和(不等待睡眠完成),我希望能够sleep 9999在 bash 历史记录中看到。
此处的大多数其他解决方案无法解决此问题的原因是,他们正在使用PROMPT_COMMANDor将历史更改写入历史文件PS1,这两者都执行得太晚,只有在sleep 9999命令完成后。
Yar*_*k T 11
是的,所以最后这让我很恼火,找到了一个不错的解决方案:
# Write history after each command
_bash_history_append() {
builtin history -a
}
PROMPT_COMMAND="_bash_history_append; $PROMPT_COMMAND"
Run Code Online (Sandbox Code Playgroud)
这样做是对该线程中所说内容的某种合并,除了我不明白为什么要在每个命令后重新加载全局历史记录。我很少关心其他终端中发生的事情,但我总是运行一系列命令,比如在一个终端中:
make
ls -lh target/*.foo
scp target/artifact.foo vm:~/
Run Code Online (Sandbox Code Playgroud)
(简化示例)
而在另一个:
pv ~/test.data | nc vm:5000 >> output
less output
mv output output.backup1
Run Code Online (Sandbox Code Playgroud)
我不希望共享命令
Tob*_*oby 10
这是我使用的替代方案。这很麻烦,但它解决了@axel_c 提到的问题,有时您可能希望在每个终端中有一个单独的历史实例(一个用于 make,一个用于监控,一个用于 vim 等)。
我保留了一个单独的附加历史文件,我会不断更新。我将以下内容映射到热键:
history | grep -v history >> ~/master_history.txt
Run Code Online (Sandbox Code Playgroud)
这会将当前终端的所有历史记录附加到您的主目录中名为 master_history.txt 的文件中。
我还有一个单独的热键来搜索主历史文件:
cat /home/toby/master_history.txt | grep -i
Run Code Online (Sandbox Code Playgroud)
我用猫 | grep 因为它将光标留在最后以输入我的正则表达式。一个不那么难看的方法是在你的路径中添加几个脚本来完成这些任务,但热键可以满足我的目的。我还会定期从我使用过的其他主机中提取历史记录并将该历史记录附加到我的 master_history.txt 文件中。
能够快速搜索并找到您使用的棘手的正则表达式或您在 7 个月前提出的奇怪的 perl one-liner 总是很好的。
我可以为最后一个提供修复:确保 env 变量 HISTCONTROL 没有指定“ignorespace”(或“ignoreboth”)。
但是我对多个并发会话感到痛苦。它在 bash 中处理得不好。
小智 7
我选择将历史记录放在一个 file-per-tty 中,因为多个人可以在同一台服务器上工作 - 将每个会话的命令分开,以便于审核。
# Convert /dev/nnn/X or /dev/nnnX to "nnnX"
HISTSUFFIX=`tty | sed 's/\///g;s/^dev//g'`
# History file is now .bash_history_pts0
HISTFILE=".bash_history_$HISTSUFFIX"
HISTTIMEFORMAT="%y-%m-%d %H:%M:%S "
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=5000
Run Code Online (Sandbox Code Playgroud)
历史现在看起来像:
user@host:~# test 123
user@host:~# test 5451
user@host:~# history
1 15-08-11 10:09:58 test 123
2 15-08-11 10:10:00 test 5451
3 15-08-11 10:10:02 history
Run Code Online (Sandbox Code Playgroud)
文件看起来像:
user@host:~# ls -la .bash*
-rw------- 1 root root 4275 Aug 11 09:42 .bash_history_pts0
-rw------- 1 root root 75 Aug 11 09:49 .bash_history_pts1
-rw-r--r-- 1 root root 3120 Aug 11 10:09 .bashrc
Run Code Online (Sandbox Code Playgroud)
这是我对@lesmana 的回答的改进。主要区别在于并发窗口不共享历史记录。这意味着您可以继续在您的窗口中工作,而无需将其他窗口的上下文加载到您当前的窗口中。
如果您明确输入“历史”,或者如果您打开一个新窗口,那么您将获得所有先前窗口的历史记录。
此外,我使用这种策略来存档在我的机器上输入的每个命令。
# Consistent and forever bash history
HISTSIZE=100000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups
_bash_history_sync() {
builtin history -a #1
HISTFILESIZE=$HISTSIZE #2
}
_bash_history_sync_and_reload() {
builtin history -a #1
HISTFILESIZE=$HISTSIZE #2
builtin history -c #3
builtin history -r #4
}
history() { #5
_bash_history_sync_and_reload
builtin history "$@"
}
export HISTTIMEFORMAT="%y/%m/%d %H:%M:%S "
PROMPT_COMMAND='history 1 >> ${HOME}/.bash_eternal_history'
PROMPT_COMMAND=_bash_history_sync;$PROMPT_COMMAND
Run Code Online (Sandbox Code Playgroud)
小智 6
这里我要指出一个问题
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Run Code Online (Sandbox Code Playgroud)
和
PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"
Run Code Online (Sandbox Code Playgroud)
如果你运行 source ~/.bashrc,$PROMPT_COMMAND 会像
"history -a; history -c; history -r history -a; history -c; history -r"
Run Code Online (Sandbox Code Playgroud)
和
"history -a; history -n history -a; history -n"
Run Code Online (Sandbox Code Playgroud)
每次运行“source ~/.bashrc”时都会发生这种重复。您可以在每次运行 'source ~/.bashrc' 后通过运行 'echo $PROMPT_COMMAND' 来检查 PROMPT_COMMAND。
您可以看到一些命令显然已损坏:“history -n history -a”。但好消息是它仍然有效,因为其他部分仍然形成一个有效的命令序列(只是由于重复执行一些命令而涉及一些额外的成本。而且不是那么干净。)
我个人使用以下简单版本:
shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r"
Run Code Online (Sandbox Code Playgroud)
它具有大部分功能,而没有上述问题。
另一点要说明的是:真的没有什么神奇的。PROMPT_COMMAND 只是一个普通的 bash 环境变量。在您获得 bash 提示($ 符号)之前,其中的命令会被执行。例如,您的 PROMPT_COMMAND 是“echo 123”,并且您在终端中运行“ls”。效果就像运行“ls; echo 123”。
$ PROMPT_COMMAND="echo 123"
Run Code Online (Sandbox Code Playgroud)
输出(就像运行 'PROMPT_COMMAND="echo 123"; $PROMPT_COMMAND'):
123
Run Code Online (Sandbox Code Playgroud)
运行以下命令:
$ echo 3
Run Code Online (Sandbox Code Playgroud)
输出:
3
123
Run Code Online (Sandbox Code Playgroud)
“history -a”用于将内存中的历史命令写入~/.bash_history
“history -c”用于清除内存中的历史命令
"history -r" 用于从 ~/.bash_history 读取历史命令到内存
在此处查看历史命令说明:http : //ss64.com/bash/history.html
PS:正如其他用户所指出的,导出是不必要的。请参阅:在 .bashrc 中使用导出
| 归档时间: |
|
| 查看次数: |
227869 次 |
| 最近记录: |