一、为什么要学习 history 命令 ?
history命令是bash shell 内置命令,history命令有助于我们缩短输入命令的时间,达到节省命令快捷操作的要求。我们也可以通过查询history命令,从而审计操作日志。同时,我们可以隐藏一些含有敏感信息的命令输入,使系统更加安全。
二、history 命令常见用法 ?
语法:
history [n | -c | -rnaw histfile]
参数:
n:数字,列出最近的 n 条历史命令
-c:将当前shell 缓存中的 history 内容全部清除
-a:将当前shell缓存中的history 内容append附加到 histfile 中,如果没有指定 histfile,则默认写入 ~/.bash_histroy
-r:将 histfile 中的内容读取到当前shell的缓存中
-w:将当前shell缓存的history历史列表写入到指定的文件
-a: 追加本次会话新执行的命令历史列表至历史文件,因为多终端所以如果想看当前都发生了什么操作就可以执行-a进行查看
-n: 读历史文件(本地数据)中未读过的行到历史列表(内存数据)
-r: 读历史文件(本地数据)附加到历史列表(内存数据)
-w: 保存历史列表(内存数据)到指定的历史文件(本地数据)
-s: 展开历史参数成一行,附加在历史列表后。用于伪造命令历史
n:数字,列出【最近】的 n 条历史命令,默认为10
[root@web ~]# history 5 997 ls 998 exit 999 history 1000 exit 1001 history
-c : 清空命令历史(使用该命令之后,仅对当前shell进程生效, exit 退出后重新进入,原来 .bash_history的内容会重新入读内存中)
要想彻底清空历史命令,需要先将 .bash_history的内容删除,接着使用 history -c, 这样才会彻底清空命令历史。
[root@web ~]# history ... 996 pstree 997 exit 998 tail -f /var/log/ldap.log 999 ls 1000 exit 1001 history [root@web ~]# history -c [root@web ~]# history 3 history [root@web ~]# > .bash_history [root@web ~]# exit logout
-d:删除历史命令中指定的的记录; 比如我们想删除命令历史中的999行命令记录,直接使用 history -d 999 即可,然后用 history 查看命令的最后几行,发现原来999行的历史命令被下一行的命令所取代
[root@web ~]# history 10 997 ls 998 exit 999 history 1000 exit 1001 history 1002 vi .bash_history [root@web ~]# history -d 999 [root@web ~]# history 10 998 exit 999 exit 1000 history 1001 vi .bash_history 1002 ls 1003 history 1004 history 5 1005 history 10 1006 history -d 999 1007 history 10
-r:读取历史文件到历史列表(将 .bash_history重新读取一遍,写入到当前bash进程的内存中)
(如果当前两个终端同时登录Linux系统, root(tty1)输入 n 条命令, root(tty2)也输入 m 条命令并且将内存中的命令历史通过 histroy -a 刷新到 .bash_history文件中, 那么 root(tty1)可以直接执行 history -r ,将root(tty2)写入到 .bashr_history文件中记录直接读取到 当前bash进程的histoty命令历史内存中)
-a:将bash 内存中历史命令追加到 .bash_history 历史命令文件中, 默认只有退出 shell 是才会保存
-w:保存历史列表到指定的历史文件(history -w /PATH/TO/SOMEFILE 将内存中命令执行的历史列表保存到指定的 /PATH/TO/SOMEFILE中)
[root@web ~]# history -w /tmp/history.log [root@web ~]# cat /tmp/history.log ps -ef ls ls -l cat /etc/issue history -w /tmp/history.log
三、history 工作机制
# !n :调用第n条命令
# !-n:调用倒数第n条命令
# !!:执行上一条命令
# !$:引用前一个命令的最后一个参数同组合键Esc,.
# !n:^ 调用第n条命令的第一个参数
# !n:$ 调用第n条命令的最后一个参数
# !m:n 调用第m条命令的第n个参数
# !n:* 调用第n条命令的所有参数
# !string:执行命令历史中最近一个以指定string开头的命令
# !string:^ 从命令历史中搜索以string 开头的命令,并获取它的第一个参数
# !string:$ 从命令历史中搜索以string 开头的命令,并获取它的最后一个参数
# !string:n 从命令历史中搜索以string 开头的命令,并获取它的第n个参数
# !string:* 从命令历史中搜索以string 开头的命令,并获取它的所有参数
常用的快捷键
执行上一次命令
!!
搜索历史命令:
Ctrl + R
重新调用前一个命令中最后一个参数:
!$
Esc + .(点击Esc键后松开,然后点击. 键)
这两个很常用,特别是Esc + .
我们在创建文件后,通常会对其进行修改或其他的读操作,这时候键入命令后利用上述快捷键即可快速补全所需命令。
四、history 工作机制
history工作机制:当用户登录系统并启动bash时,会读取 histfile 变量指定文件中的历史记录到当前shell进程的内存中,我们在此bash中的所有操作,也会缓存在内存里面, 只有在bash退出后,才会把内存中的历史记录 flush 到 histfile 变量指定的文件中。
所以会出现这种情况:
我和同事用不同的机器登录到同一台linux服务器上, 我用history命令只能查看自己终端所操作的命令,如果我也想看到所有连接到此服务器的终端所操作的命令,应该如何操作呢?
回答是: 看不到, 在用户退出登录之前,命令历史记录全部在内存中,没有写入到文件。
通常 .bash_history 在每个用户的 $HOME 目录下,但这是查看上次用户所操作的历史记录。
五、history 相关环境变量
HISTFILESIZE:命令历史文件记录的条数
HISTSIZE:命令历史记录的条数
[root@web ~]# echo $HISTSIZE 1000
HISTFILE:指定历史文件,默认为每个用户家目录下: ~/.bash_history
HISTTIMEFORMAT="%F %T ":显示时间,可以记录命令执行的时间
[root@web ~]# HISTTIMEFORMAT="%F %T " [root@web ~]# history 10 2017-06-23 07:05:15 ps -ef 11 2017-06-23 07:05:16 ls 12 2017-06-23 07:05:18 ls -l 13 2017-06-23 07:05:29 cat /etc/issue
HISTTIMEFORMAT="$(hostname) %F %T ":显示更加详细的主机名和命令执行时间
[root@web ~]# HISTTIMEFORMAT="$(hostname) %F %T " [root@web ~]# history 10 web 2017-06-23 07:05:15 ps -ef 11 web 2017-06-23 07:05:16 ls
HISTTIMEFORMAT="$(tty) %F %T ":显示用户登录终端和命令执行时间
[root@web ~]# HISTTIMEFORMAT="$(tty) %F %T " [root@web ~]# history 10 /dev/pts/2 2017-06-23 07:05:15 ps -ef 11 /dev/pts/2 2017-06-23 07:05:16 ls
HISTIGNORE="str1:str2:...": 忽略以冒号分隔的 str1, str2 历史记录
会忽略接下来输入凡是有 str1:str2 的命令
控制命令历史的记录方式
HISTCONTROL=
ignoredups:忽略重复的命令, “连续且相同”方为【重复】
ignorespace:忽略所有以空白开头的命令
ignoreboth:ignoredups && ignorespace
erasedups:删除重复命令,减小 history 的大小
注意:命令直接在命令行进行环境变量的设置,执行时间段仅限于该脚本,设置完变量会立即生效,但是exit退出当前脚本之后,环境变量就会失效;将环境变量写入配置文件中,/etc/profile(全局变量,对所有用户有效)或 ~/.bash_profile(单用户模式,仅对该用户有效),写入配置文件中不会立即生效,但是需要重新登录之后生效。
参考:
http://www.tuicool.com/articles/B7FFVrm