history 命令
使用 history
可以显示历史记录和执行过的命令。命令历史是被保存在内存中的,当退出当前的 shell 时会自动保存到历史命令文件 ~/.bash_history
当中 ,当登录 shell 时则从这个文件中读取以前的命令到命令历史。
常用的选项:
history n
列出最近执行过的n条命令history -c
清除所有历史命令histoty -w
将缓冲区命令写入历史命令文件~/.bash_history
history -d 5
删除历史记录中序号为 5 的命令
配置的定义
在内存中仅能够存储 1000 条历史命令,该数量是由环境变量 HISTSIZE
进行控制的。这个值可以在 /etc/profile
中进行修改,修改成功后在下次登录时即可生效。
1 | # vim +/HISTSIZE /etc/profile |
默认情况下 history
不显示命令的执行时间,但是系统已经记录。同样,可以在 /etc/profile
进行修改,修改成功后在下次登录时即可生效
1 | export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL # 在这一行下面添加如下两行 |
这里需要说明一下,%F %T
等同于 %Y-%m-%d %H:%M:%S
,和 date
命令的用法一致,表示的是年月日和时分秒,而 |
竖线加个空格没有其他特殊意义,只是为了作为分隔符,能够更清晰地区分不同的多条命令。
注意事项
当同一用户同时登录多个 bash 时,只有最后一个退出的会写入 bash_history
,其他的会被覆盖掉。
神奇的叹号 “!”
执行上一条命令
使用键盘 ↑
键可以很快再执行一次上一条命令,与之效果相同的是使用两个叹号, !!
代表了上一条命令,例如:
1 | [user1@study ~]$ which head |
当要想操作一个文件,但是漏掉了操作命令,可以这样来补救:
1 | [user1@study ~]$ /etc/issue |
多数情况下,还是习惯再次从头敲一次命令,但是当命令行的参数比较长(例如很长的文件路径)的时候用上面的方法会显得更高效。
调用上条命令的参数
如果要执行一条很长很长的命令,包含了很多参数,比如在进行源码包编译安装的命令,敲错了一个字母或者多了一个选项,使用退格键删除觉得又慢又很麻烦,这时候可以试试下面的方法。
调用上条命令最后一个参数
在命令行使用 !$
或 !:$
可以很方便地引用上一条命令的最后一个参数:
1 | [user1@study ~]$ sudo ifconfig 192.168.127.127 eth1 |
和 !$
有着相同功能的还有一个快捷键:Esc
+ .
,当执行一次 Esc
+ .
的时候,跟 !$
功能一样,但是在多次重复执行 Esc
+ .
的时候,则会倒序切换历史命令的最后一个参数。
1 | [user1@study ~]$ echo 192.168.1.1 |
使用 !$:p
或者 !:$:p
则只会打印输出上一条命令的最后参数,但不执行。
1 | [user1@study ~]$ !$:p |
调用上条命令但剔除最后一个参数
有时候命令行会从别处粘贴一个字符串来操作,但是由于失误多复制了一部分并且执行时出错,此时 !:-
就派上用场了:
1 | [user1@study ~]$ ip route show match 192.168.127.127 dev |
使用 !:-:p
则只会打印输出,但不执行。
1 | [user1@study ~]$ ip route show match 192.168.127.127 dev |
调用上条命令第一个参数
如果想引用上一条命令的第一个参数,使用 !^
或 !:^
或 !:1
即可:
1 | [user1@study ~]$ cp /etc/sysconfig/network-scripts/ifcfg-eth0 /tmp/ |
使用 !^:p
或 !:^:p
或 !:1:p
则只会打印输出,但不执行。
1 | [user1@study ~]$ echo 192.168.1.3 |
调用上条命令中指定的参数
如果只想用上条命令中某个参数呢,则按照 ![命令名]:[参数号]
的规则即可,并且命令名可以省略。例如:
1 | [user1@study ~]$ sudo ip route add 114.114.114.114 via 192.168.127.2 dev eth0 |
对于 sudo
命令来说 114.114.114.114
是他是它的第 4 个参数。
使用 ![命令名]:[参数号]:p
则只会打印输出,但不执行。
1 | [user1@study ~]$ ip route show match !:4:p |
调用上条命令所有参数
如果一条操作命令后面有很多选项和参数,但是我们把命令敲错了,这时候该怎么办呢?此时我们再重新敲对操作命令,使用 !*
或者 !:*
将上一条命令的所有参数引用下来即可:
1 | [user1@study ~]$ ips route add 192.168.127.128/32 dev 192.168.127.127 dev eth1 |
第一条命令执行失败是因为命令敲错,第二条命令执行失败是因为当前用户是普通用户,权限不允许,但是命令以及参数是没错的。
使用 !*:p
或者 !:*:p
则只会显示出上一条命令的所有参数,但不执行。
1 | [user1@study ~]$ ips route add 192.168.127.128/32 dev 192.168.127.127 dev eth1 |
调用上条以关键字开头的命令
使用 !string
则会执行命令历史中最近一个以指定字符串(string)开头的命令,例如:
1 | [user1@study ~]$ !wc |
使用 !string:p
则只打印输出符合条件的命令,但不执行。
1 | [user1@study ~]$ !wc:p |
替换上条命令的参数
如果上一条命令很长,而且有个参数不小心敲错了该怎么办?使用 ^no^yes
就可以将上条命令中错误的参数 no
改成 yes
并再次执行一次。比如:
1 | [user1@study ~]$ grp -i 163 /etc/yum.repos.d/CentOS-Base.repo |
但是这种方法只能替换上条命令中第一次被匹配到的参数:
1 | [user1@study ~]$ ip route show match 192.168.10.10 |
如果想把上条命令中所有匹配到的参数全部替换可以这样做:
1 | [user1@study ~]$ ip route show match 192.168.10.10 |
对上条以关键字开头的命令也是可以做替换的,例如将上一条 scp 命令中的所有 10
替换为 123
1 | !scp:gs/10/123 |
逻辑非
列出除了 cfg
结尾以外的所有文件:
1 | [user1@study ~]$ ls |
其他
!n
:执行历史命令中第 n 条命令。!-n
:执行历史命令中倒数第 n 条命令。!?str?
:最近一条包含 str 的命令。↑
或Ctrl
+p
:引用上一条命令。↓
或Ctrl
+n
:引用下一条命令。Ctrl
+r
:按下这个快捷键 ,然后输入关键字搜索历史命令,按Enter
执行命令。