linux 历史命令
shell 在执行某个命令后,默认会将其记录在内存中,当用户退出时,会将这些记录通过差异的方式写入到文件中(~/.bash_history),当你登录到 shell 时,shell 会将文件中的历史命令加载到内存中。
我们可以通过 history 命令查看 shell 中的历史记录
it@workstation:~$ history
1 apt-get update
2 sudo apt-get update
3 sudo apt install -y ansible
4 ansible --version
5 mkdir ansible
6 cd ansible/
7 cp /etc/ansible/ansible.cfg .
8 cp /etc/ansible/hosts .
9 vim /etc/hosts
10 sudo apt install -y vim
11 vim /etc/hosts
12 sudo vim /etc/hosts
13 cat /etc/hosts | grep server
14 history
15 cd
16 history
查看 ~/.bash_history 文件内容
it@workstation:~$ cat .bash_history
cd
history
apt-get update
sudo apt-get update
sudo apt install -y ansible
ansible --version
mkdir ansible
cd ansible/
cp /etc/ansible/ansible.cfg .
cp /etc/ansible/hosts .
vim /etc/hosts
sudo apt install -y vim
vim /etc/hosts
sudo vim /etc/hosts
cat /etc/hosts | grep server
history
cd
history
cat .bash_history
exit
我们可以通过 -a 选项,在不退出当前 shell 的情况下,将历史记录写入到 .bash_history 文件中;
it@workstation:~$ cat .bash_history
cd
history
apt-get update
sudo apt-get update
sudo apt install -y ansible
ansible --version
mkdir ansible
cd ansible/
cp /etc/ansible/ansible.cfg .
cp /etc/ansible/hosts .
vim /etc/hosts
sudo apt install -y vim
vim /etc/hosts
sudo vim /etc/hosts
cat /etc/hosts | grep server
history
cd
history
cat .bash_history
exit
it@workstation:~$ history -a
it@workstation:~$ cat .bash_history
cd
history
apt-get update
sudo apt-get update
sudo apt install -y ansible
ansible --version
mkdir ansible
cd ansible/
cp /etc/ansible/ansible.cfg .
cp /etc/ansible/hosts .
vim /etc/hosts
sudo apt install -y vim
vim /etc/hosts
sudo vim /etc/hosts
cat /etc/hosts | grep server
history
cd
history
cat .bash_history
exit
cat .bash_history
history
history -d 22
history 5
history
cat .bash_history
history -a
可以通过 -c 选项,清除历史记录
it@workstation:~$ history -c
it@workstation:~$ history
1 history
* 这里清除的只是内存中的,.bash_history 的内容不会有任何的变化;
当你需要时,你可以通过 -r 选项,从文件中读取历史记录到内存;
it@workstation:~$ history -r
it@workstation:~$ history
1 history -r
2 cd
3 history
4 apt-get update
5 sudo apt-get update
6 sudo apt install -y ansible
7 ansible --version
8 mkdir ansible
9 cd ansible/
10 cp /etc/ansible/ansible.cfg .
11 cp /etc/ansible/hosts .
12 vim /etc/hosts
13 sudo apt install -y vim
14 vim /etc/hosts
15 sudo vim /etc/hosts
16 cat /etc/hosts | grep server
17 history
18 cd
19 history
20 cat .bash_history
21 exit
22 cat .bash_history
23 history
24 history -d 22
25 history 5
26 history
27 cat .bash_history
28 history -a
29 exit
30 history
如果需要,我们可以通过 -w 选项加文件名,导出历史命令记录
it@workstation:~$ history -w outfile
it@workstation:~$ cat outfile
cd
history
apt-get update
sudo apt-get update
sudo apt install -y ansible
ansible --version
mkdir ansible
cd ansible/
cp /etc/ansible/ansible.cfg .
cp /etc/ansible/hosts .
vim /etc/hosts
sudo apt install -y vim
vim /etc/hosts
sudo vim /etc/hosts
cat /etc/hosts | grep server
history
cd
history
cat .bash_history
exit
cat .bash_history
history
history -d 22
history 5
history
cat .bash_history
history -a
exit
history
history -w outfile
* 导出的是来自内存的历史记录
更多关于 history 命令的用法,你可以通过 history --help 查找关于 history 命令的帮助;
历史命令记录相关的变量:
HISTCONTRO: 控制命令历史记录的方式:
- ignoredups:Redhat 的默认值,可忽略重复的命令,连续且相同为“重复”
- ignorespace:忽略所有以空白开头的命
- ignoreboth:Ubuntu 的默认值,相当于ignoredups, ignorespace 的组合
- erasedups:删除重复命令
HISTFILE: 表示保存当前用户记录历史记录的文件;
HISTSIZE: 表示 history 命令可以输出的命令数量,
HISTFILESIZE: 表示 .bash_history 文件中可以保存的历史命令数量;
it@workstation:~$ set | grep HIST
HISTCONTROL=ignoreboth
HISTFILE=/home/it/.bash_history
HISTFILESIZE=2000
HISTSIZE=1000
* 在 Ubuntu 中,HISTFILESIZE 的值为 2000,HISTSIZE 的值为 1000,所以 history 命令只能输出 .bash_history 文件中的最后 1000 条命令;
* 在 Redhat 中,这两个值是相等的,都是 1000
如果你想修改这些变量的值,你可以在 /etc/profile(当前用户生效)或 ~/.bash_profile(当前用户生效) 文件中,添加这些变量,并给它们指定新值;
it@workstation:~$ vim .bash_profile
it@workstation:~$ source .bash_profile
it@workstation:~$ set | grep HIST
HISTCONTROL=ignoreboth
HISTFILE=/home/it/.bash_history
HISTFILESIZE=2000
HISTSIZE=2000
it@workstation:~$
还有一个变量,并没有在这里显示出来,因为它的值为空,如果你想使用它,就需要直接添加它以及它的值到 profile 文件中,这个变量就是 HISTTIMEFORMAT,我们可以通过它来记录执行命令的时间;
it@workstation:~$ echo $HISTTIMEFORMAT
it@workstation:~$ vim .bash_profile
it@workstation:~$ cat .bash_profile
HISTSIZE=2000
HISTTIMEFORMAT="%F %T "
it@workstation:~$ source .bash_profile
it@workstation:~$ history
1 2021-01-28 13:15:38 history -w outfile
2 2021-01-28 13:15:41 cat outfile
3 2021-01-28 13:17:18 history -h
4 2021-01-28 13:17:23 history --help
5 2021-01-28 13:23:20 set | grep HIS
6 2021-01-28 13:23:36 set | grep HIST
7 2021-01-28 13:38:55 vim .bash_profile
8 2021-01-28 13:39:16 source .bash_profile
9 2021-01-28 13:39:20 set | grep HIST
10 2021-01-28 13:42:46 echo $HISTTIMEFORMAT
11 2021-01-28 13:47:39 vim .bash_profile
12 2021-01-28 13:49:40 cat .bash_profile
13 2021-01-28 13:49:51 source .bash_profile
14 2021-01-28 13:49:54 history
* %F 和 %T 是显示时间的格式,具体可以参考 date 命令;
当我们需要重复执行已经执行过的命令,就可以使用一些特殊字符来调用这些历史命令。当我们需要执行的历史命令是最近执行过的,我们可以通过方向键的上键,往上翻历史记录,找到你想要指定的命令,执行即可。
我们可以通过 !n 执行第 n 条命令
it@workstation:~$ history
1 2021-01-28 13:15:38 history -w outfile
2 2021-01-28 13:15:41 cat outfile
3 2021-01-28 13:17:18 history -h
4 2021-01-28 13:17:23 history --help
5 2021-01-28 13:23:20 set | grep HIS
6 2021-01-28 13:23:36 set | grep HIST
7 2021-01-28 13:38:55 vim .bash_profile
8 2021-01-28 13:39:16 source .bash_profile
9 2021-01-28 13:39:20 set | grep HIST
10 2021-01-28 13:42:46 echo $HISTTIMEFORMAT
11 2021-01-28 13:47:39 vim .bash_profile
12 2021-01-28 13:49:40 cat .bash_profile
13 2021-01-28 13:49:51 source .bash_profile
14 2021-01-28 13:49:54 history
it@workstation:~$ !9
set | grep HIST
HISTCONTROL=ignoreboth
HISTFILE=/home/it/.bash_history
HISTFILESIZE=2000
HISTSIZE=2000
HISTTIMEFORMAT='%F %T '
* 不过在日常工作中,这种方式使用的不多,因为在很多情况下,你并不知道,你想要执行的历史命令的序号
通过 !-n 执行倒数第 n 个命令
it@workstation:~$ history
1 2021-01-28 13:15:38 history -w outfile
2 2021-01-28 13:15:41 cat outfile
3 2021-01-28 13:17:18 history -h
4 2021-01-28 13:17:23 history --help
5 2021-01-28 13:23:20 set | grep HIS
6 2021-01-28 13:23:36 set | grep HIST
7 2021-01-28 13:38:55 vim .bash_profile
8 2021-01-28 13:39:16 source .bash_profile
9 2021-01-28 13:39:20 set | grep HIST
10 2021-01-28 13:42:46 echo $HISTTIMEFORMAT
11 2021-01-28 13:47:39 vim .bash_profile
12 2021-01-28 13:49:40 cat .bash_profile
13 2021-01-28 13:49:51 source .bash_profile
14 2021-01-28 13:49:54 history
15 2021-01-28 13:51:37 date +%F-%T
16 2021-01-28 13:51:45 date +%F %T
17 2021-01-28 13:51:50 date '+%F %T'
18 2021-01-28 13:53:44 set | grep HIST
19 2021-01-28 14:13:42 history
it@workstation:~$ !-3
date '+%F %T'
2021-01-28 14:13:54
通过执行 !String 执行最后一个以指定字符串开头的命令,如,通过 !?tor 执行最后一个包含 tor 的命令;
it@workstation:~$ !da
date '+%F %T'
2021-01-28 14:15:19
通过执行 !?String 执行最后一个包含指定字符串的命令,如,通过 !da 执行最后一个以 da 开头的命令;
it@workstation:~$ !?tor
history
1 2021-01-28 13:15:38 history -w outfile
2 2021-01-28 13:15:41 cat outfile
3 2021-01-28 13:17:18 history -h
4 2021-01-28 13:17:23 history --help
5 2021-01-28 13:23:20 set | grep HIS
6 2021-01-28 13:23:36 set | grep HIST
7 2021-01-28 13:38:55 vim .bash_profile
8 2021-01-28 13:39:16 source .bash_profile
9 2021-01-28 13:39:20 set | grep HIST
10 2021-01-28 13:42:46 echo $HISTTIMEFORMAT
11 2021-01-28 13:47:39 vim .bash_profile
12 2021-01-28 13:49:40 cat .bash_profile
13 2021-01-28 13:49:51 source .bash_profile
14 2021-01-28 13:49:54 history
15 2021-01-28 13:51:37 date +%F-%T
16 2021-01-28 13:51:45 date +%F %T
17 2021-01-28 13:51:50 date '+%F %T'
18 2021-01-28 13:53:44 set | grep HIST
19 2021-01-28 14:13:42 history
20 2021-01-28 14:13:54 date '+%F %T'
21 2021-01-28 14:17:51 history
通过 Ctrl + R 进行历史命令搜索,找到后通过回车运行该历史命令;
it@workstation:~$
(reverse-i-search)`his': history
* 通过 Ctrl + G 退出搜索
通过 !:1 调用前一个命令的第一个参数;
it@workstation:~$ ls /etc/hosts /etc/profile
/etc/hosts /etc/profile
it@workstation:~$ ls !:1
ls /etc/hosts
/etc/hosts
通过 !$ 调用前一个命令的最后一个参数
it@workstation:~$ ls /etc/hosts /etc/profile
/etc/hosts /etc/profile
it@workstation:~$ ls !$
ls /etc/profile
/etc/profile
* 这个也可以通过先按 ESC,然后按 . 或 Alt + . 来实现(有些终端软件 Alt + . 快捷键被其他功能占用,需要重新配置。)