一、为什么要学习 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