背景:history是Linux中常会用到内容,在工作中一些用户会突然发现其安装不了某个软件,于是寻求运维人员的帮助,而不给你说明他到底做了哪些坑爹的操作。此时你第一件要做的就是要查看其history命令历史。查看后兴许你就会发现他到底干了什么坑爹的操作。
history可以让你在一定情况下快速定位问题所在。

本文的history介绍及其实践都是来自CentOS7.2环境
[root@localhost ~]# cat /etc/RedHat-release  
CentOS Linux release 7.2.1511 (Core)

history的介绍
history是shell的内置命令,其内容在系统默认的shell的man手册中。
history是显示在终端输入并执行的过命令,系统默认保留1000条。
[root@localhost ~]# history 
    1  ls
    2  vi /etc/sysconfig/network-scripts/ifcfg-eno16777728 
    3  service network restart 
    4  ifconfig
    5  ping www.linuxidc.com 
    6  systemctl disable firewalld.service  
    7  systemctl stop firewalld.service  
    8  exit
    9  ls
  10  type which
  11  which ls
  12  file /usr/bin/ls
  13  which clock 
  14  file /usr/sbin/clock
  15  man which
  16  man what 
  17  man who
  18  who
  19  man who
  20  man w 
  21  man who
  22  who -q 
  23  man w 
  ... 
  .. 
  .

系统在关闭后会将现有history内容保存在文件~/.bash_history

与history相关的环境变量
HISTFILE          指定存放历史文件位置,默认位置在~/.bash_profile(针对用户)、 
      /etc/profile(针对全局,如果~/.bash_profile内没有相关环境变量内容则使用全局变量设置) 
HISTFILESIZE      命令历史文件记录历史的条数 
HISTSIZE          命令历史记录的条数,默认为1000 
HISTTIMEFORMAT="%F %T"  显示命令发生的时间 
HISTIGNORE="str1:str2:..." 忽略string1,string2历史 
HISTCONTROL      包含一下4项,让哪一项生效只需要让其=下面一项即可 
ignoredups:  忽略重复的命令;连续且相同方为“重复” 
ignorespace:  忽略所有以空白开头的命令 
ignoreboth:ignoredups,ignorespace 
erasedups:    删除重复命令

让上述环境变量生效方式:
1、直接在当前shell内输入相关变量,比如我们不想留存命令历史,我们把HISTSIZE设置为0
[root@localhost ~]# HISTSIZE=0 
[root@localhost ~]# history

经测试,成功。不过这种设置的局限性是其作用范围仅仅针对当前shell及其子shell,如果切换用户或登出再登入其设置失效。不过其特点是设置完立刻生效。
下面通过实验说明这个问题
[root@localhost ~]# bash 
[root@localhost ~]# history 
[root@localhost ~]# history

以上结果说明在当前shell内设置history的环境变量后,其作用范围为当前shell及子shell
Last login: Fri Jul 29 17:26:41 2016 from 10.1.250.62 
[root@localhost ~]# history 
    1  history

重新登陆后原有的history环境变量失效
2、另一种让history环境变量生效的方式是修改~/.bash_profile文件
[root@localhost ~]# vi ~/.bash_profile  
# .bash_profile 
  
# Get the aliases and functions 
if [ -f ~/.bashrc ]; then
        . ~/.bashrc 
fi
  
# User specific environment and startup programs 
  
PATH=$PATH:$HOME/bin
HISTTIMEFORMAT="%F %T "        此为新添加的history环境变量,我添加了发生命令操作的时间 
export PATH

wq保存退出。
[root@localhost ~]# history            
    1  history
    2  ll 
    3  cd
    4  hostory 
    5  history
    6  vi ~/.bash_profile  
    7  history

由结果可知变量并没有生效,我们重新登录再尝试下。
[root@localhost ~]# history 
    1  2016-07-29 20:00:29 history
    2  2016-07-29 20:00:29 ll 
    3  2016-07-29 20:00:29 cd
    4  2016-07-29 20:00:29 hostory 
    5  2016-07-29 20:00:29 history
    6  2016-07-29 20:00:29 vi ~/.bash_profile  
    7  2016-07-29 20:00:29 history
    8  2016-07-29 20:00:29 logout
    9  2016-07-29 20:00:33 history

通过上面的两个结果,我们可以发现第二种修改配置文件虽然也可以成功修改history环境变量但是其生效需要重新登陆,并不是改完就生效。但是它的特点是此修改始终有效,时效性为永久。

history命令的使用
-c: 清空命令历史
-d n: 删除历史中指定的命令,n表示命令号
#: 显示最近的#条历史
-a: 追加本次会话新执行的命令历史列表至历史文件,因为多终端所以如果想看当前都发生了什么操作就可以执行-a进行查看
-n: 读历史文件(本地数据)中未读过的行到历史列表(内存数据)
-r: 读历史文件(本地数据)附加到历史列表(内存数据)
-w: 保存历史列表(内存数据)到指定的历史文件(本地数据)
-s: 展开历史参数成一行,附加在历史列表后。用于伪造命令历史
下面来演示上面几种命令的使用
[root@localhost ~]# history 
    1  2016-07-29 20:00:29 history
    2  2016-07-29 20:00:29 ll 
    3  2016-07-29 20:00:29 cd
    4  2016-07-29 20:00:29 hostory 
    5  2016-07-29 20:00:29 history
    6  2016-07-29 20:00:29 vi ~/.bash_profile  
    7  2016-07-29 20:00:29 history
    8  2016-07-29 20:00:29 logout
    9  2016-07-29 20:00:33 history
  10  2016-07-29 20:07:41  cd
  11  2016-07-29 20:07:44  ls
  12  2016-07-29 20:07:50  history
  13  2016-07-29 20:08:12 cat /etc/profile
  14  2016-07-29 20:12:10 HISTCONTROL=ignorespace 
  15  2016-07-29 20:27:28 history -p 
  16  2016-07-29 20:27:31 history
  17  2016-07-29 20:28:10 ls /etc
  18  2016-07-29 20:28:14 history
  19  2016-07-29 20:28:57 history

清空历史
[root@localhost ~]# history -c 
[root@localhost ~]# history 
2016-07-29 20:29:26 history

从历史文件读取之前的命令历史
[root@localhost ~]# history -r  
[root@localhost ~]# history 
    1  2016-07-29 20:29:26 history
    2  2016-07-29 20:30:59 history -r  
    3  2016-07-29 20:30:59 history
    4  2016-07-29 20:30:59 ll 
    5  2016-07-29 20:30:59 cd
    6  2016-07-29 20:30:59 hostory 
    7  2016-07-29 20:30:59 history
    8  2016-07-29 20:30:59 vi ~/.bash_profile  
    9  2016-07-29 20:30:59 history
  10  2016-07-29 20:30:59 logout
  11  2016-07-29 20:31:01 history

删除指定命令历史
[root@localhost ~]# history -d 4 
[root@localhost ~]# history 
    1  2016-07-29 20:29:26 history
    2  2016-07-29 20:30:59 history -r  
    3  2016-07-29 20:30:59 history
    4  2016-07-29 20:30:59 cd
    5  2016-07-29 20:30:59 hostory 
    6  2016-07-29 20:30:59 history
    7  2016-07-29 20:30:59 vi ~/.bash_profile  
    8  2016-07-29 20:30:59 history
    9  2016-07-29 20:30:59 logout
  10  2016-07-29 20:31:01 history
  11  2016-07-29 20:32:50 history -d 4 
  12  2016-07-29 20:32:52 history

伪造历史命令
12345678910111213141516 [root@localhost ~]# history -s rm -rf /*  做下恶作剧 
[root@localhost ~]# history 
    1  2016-07-29 20:29:26 history
    2  2016-07-29 20:30:59 history -r  
    3  2016-07-29 20:30:59 history
    4  2016-07-29 20:30:59 cd
    5  2016-07-29 20:30:59 hostory 
    6  2016-07-29 20:30:59 history
    7  2016-07-29 20:30:59 vi ~/.bash_profile  
    8  2016-07-29 20:30:59 history
    9  2016-07-29 20:30:59 logout
  10  2016-07-29 20:31:01 history
  11  2016-07-29 20:32:50 history -d 4 
  12  2016-07-29 20:32:52 history
  13  2016-07-29 20:33:57 rm -rf /bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
  14  2016-07-29 20:34:00 history

我相信任谁输入history看到这个命令都会吓一身汗。

调用历史参数详解

#cmd !^ : 利用上一个命令的第一个参数做cmd的参数 
#cmd !$ : 利用上一个命令的最后一个参数做cmd的参数 
#cmd !* : 利用上一个命令的全部参数做cmd的参数 
#cmd !:n : 利用上一个命令的第n个参数做cmd的参数 
#!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 开头的命令,并获取它的所有参数

下面通过实验来实践上面的历史参数的具体用法
[root@localhost ~]# history 
    1  2016-07-29 20:29:26 history
    2  2016-07-29 20:30:59 history -r  
    3  2016-07-29 20:30:59 history
    4  2016-07-29 20:30:59 cd
    5  2016-07-29 20:30:59 hostory 
    6  2016-07-29 20:30:59 history
    7  2016-07-29 20:30:59 vi ~/.bash_profile  
    8  2016-07-29 20:30:59 history
    9  2016-07-29 20:30:59 logout
  10  2016-07-29 20:31:01 history
  11  2016-07-29 20:32:50 history -d 4 
  12  2016-07-29 20:32:52 history
  13  2016-07-29 20:33:57 rm -rf /bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
  14  2016-07-29 20:34:00 history
  15  2016-07-29 20:40:32 ls
  16  2016-07-29 20:40:33 cd
  17  2016-07-29 20:40:45 ls /etc/passwd
  18  2016-07-29 20:41:35 history

我们先使用!!来调用上一条命令

[root@localhost ~]# !! 
history
    1  2016-07-29 20:29:26 history
    2  2016-07-29 20:30:59 history -r  
    3  2016-07-29 20:30:59 history
    4  2016-07-29 20:30:59 cd
    5  2016-07-29 20:30:59 hostory 
    6  2016-07-29 20:30:59 history
    7  2016-07-29 20:30:59 vi ~/.bash_profile  
    8  2016-07-29 20:30:59 history
    9  2016-07-29 20:30:59 logout
  10  2016-07-29 20:31:01 history
  11  2016-07-29 20:32:50 history -d 4 
  12  2016-07-29 20:32:52 history
  13  2016-07-29 20:33:57 rm -rf /bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
  14  2016-07-29 20:34:00 history
  15  2016-07-29 20:40:32 ls
  16  2016-07-29 20:40:33 cd
  17  2016-07-29 20:40:45 ls /etc/passwd
  18  2016-07-29 20:41:35 history

[root@localhost ~]# !h 
history
    1  2016-07-29 20:29:26 history
    2  2016-07-29 20:30:59 history -r  
    3  2016-07-29 20:30:59 history
    4  2016-07-29 20:30:59 cd
    5  2016-07-29 20:30:59 hostory 
    6  2016-07-29 20:30:59 history
    7  2016-07-29 20:30:59 vi ~/.bash_profile  
    8  2016-07-29 20:30:59 history
    9  2016-07-29 20:30:59 logout
  10  2016-07-29 20:31:01 history
  11  2016-07-29 20:32:50 history -d 4 
  12  2016-07-29 20:32:52 history
  13  2016-07-29 20:33:57 rm -rf /bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
  14  2016-07-29 20:34:00 history
  15  2016-07-29 20:40:32 ls
  16  2016-07-29 20:40:33 cd
  17  2016-07-29 20:40:45 ls /etc/passwd
  18  2016-07-29 20:41:35 history
  19  2016-07-29 20:47:03 history
  20  2016-07-29 20:48:22 history

大家感兴趣可以一个个实验。本文就介绍到这里。

常用的快捷键
  重新调用前一个命令中最后一个参数:
  !$ 
  Esc, .(点击Esc键后松开,然后点击. 键)
这两个很常用,特别是Esc,.
我们在创建文件后,通常会对其进行修改或其他的读操作,这时候键入命令后利用上述快捷键即可快速补全所需命令。

Linux基础知识之history的详细说明的更多相关文章

  1. Linux基础知识梳理

    Linux基础知识梳理 Linux内核最初只是由芬兰人林纳斯?托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的.Linux是一套免费使用和自由传播的类Unix操作系统,是 ...

  2. Linux基础知识与基础命令

    Linux基础知识与基础命令 系统目录 Linux只有一个根目录,没有盘符的概念,文件目录是一个倒立的树形结构. 常用的目录功能 bin 与程序相关的文件 boot 与系统启动相关 cdrom 与Li ...

  3. [转帖]linux基础知识大纲

    linux基础知识大纲 https://blog.csdn.net/CSDN___LYY/article/details/80810403 1.Linux操作系统概述Linux操作系统的发展过程.创始 ...

  4. Linux基础知识入门

    [Linux基础]Linux基础知识入门及常见命令.   前言:最近刚安装了Linux系统, 所以学了一些最基本的操作, 在这里把自己总结的笔记记录在这里. 1,V8:192.168.40.10V1: ...

  5. 运维之Linux基础知识(三)

    运维之Linux基础知识(三) 1. 查看文本 cat tac more less head tail 1.1 cat 连接并显示文件 cat -n:在显示的时候,将每一行编号 -E:显示结束符$ - ...

  6. Linux基础知识第九讲,linux中的解压缩,以及软件安装命令

    目录 Linux基础知识第九讲,linux中的解压缩,以及软件安装命令 一丶Linux Mac Windows下的压缩格式简介 2.压缩以及解压缩 3.linux中的软件安装以及卸载 1.apt进行安 ...

  7. Linux基础知识第八讲,系统相关操作命令

    目录 Linux基础知识第八讲,系统相关操作命令 一丶简介命令 2.磁盘信息查看. 3.系统进程 Linux基础知识第八讲,系统相关操作命令 一丶简介命令 时间和日期 date cal 磁盘和目录空间 ...

  8. Linux基础知识第七讲,用户权限以及用户操作命令

    目录 Linux基础知识第七讲,用户权限以及用户操作命令 一丶简介linux用户,用户权限,组的概念. 1.1 基本概念 1.2 组 1.3 ls命令查看权限. 二丶用户权限修改命令 1.chmod ...

  9. linux基础知识的总结

    例如以下内容是我对linux基础知识的总结,由于本人在初期学习linux的时候走了不少的弯路,对于基础的掌握耗费了不少的时间,所以为了后来者对linux的基础部分有个清晰的了解,特对基础知识进行了总结 ...

随机推荐

  1. UVA 10972 - RevolC FaeLoN(边-双连通分量)

    UVA 10972 - RevolC FaeLoN option=com_onlinejudge&Itemid=8&page=show_problem&category=547 ...

  2. python分析apahce网站日志的例子

    有关python实现apahce网站日志分析的方法. 应用到:shell与python数据交互.数据抓取,编码转换 #coding:utf-8 #!/usr/bin/python'''程序说明:apa ...

  3. 可靠的功能測试--Espresso和Dagger2

    欢迎Follow我的GitHub, 关注我的CSDN. 可靠的功能測试, 意味着在不论什么时候, 获取的測试结果均同样, 这就须要模拟(Mock)数据. 測试框架能够使用Android推荐的Espre ...

  4. lua内存管理

    本文内容基于版本:Lua 5.3.0 Lua内存管理器规则 Lua允许用户自定义内存管理器,并在创建Lua虚拟机(lua_State实例)时传入.当然自定义内存管理器必须遵循Lua已定义的一些行为规则 ...

  5. maven(4)------maven核心pom.xml文件常用元素分析

    在maven项目中,pom文件是核心文件 pom.xml: <?xml version="1.0" encoding="UTF-8"?> <p ...

  6. 找不到编译动态表达式所需的一种或多种类型。是否缺少对 Microsoft.CSharp.dll 和 System.Core.dll 的引用?

    提示“找不到编译动态表达式所需的一种或多种类型.是否缺少对 Microsoft.CSharp.dll 和 System.Core.dll 的引用? ”错误 解决方法:   将引入的COM对象(misc ...

  7. Oracle PLSQL Demo - 20.弱类型REF游标[没有指定查询类型,也不指定返回类型]

    declare Type ref_cur_variable IS REF cursor; cur_variable ref_cur_variable; v_ename ); v_deptno ); v ...

  8. nodejs字符串操作

    nodejs的字符串操作需要引入querystring对象,querystring对象的方法有: 1:querystring.stringify(“对象”,“分隔符”,“分配符”),用来将一个json ...

  9. qt离线下载

    http://www.qtcn.org/bbs/read-htm-tid-1075.html

  10. 多核CPU上python多线程并行的一个假象

    GIL 与 Python 线程的纠葛 GIL 是什么东西?它对我们的 python 程序会产生什么样的影响?我们先来看一个问题.运行下面这段 python 程序,CPU 占用率是多少? # 请勿在工作 ...