# 命令别名与历史命令

# 命令别名设置:alias、unalias

命令别名就是你可以把一长串指令指定一个简短的名称,在键入指令的时候使用简短的名称来达到调用一长串指令的目的。例如:ls -al|more 查看隐藏文档并且翻页查看,觉得这串指令太长了,可以通过下面的指令来设置别名

[mrcode@study ~]$ alias lm='ls -al | more'
[mrcode@study ~]$ lm
total 68
drwx------. 18 mrcode mrcode  4096 Nov 11 10:20 .
drwxr-xr-x.  4 root   root      42 Oct  8 23:01 ..
-rw-------.  1 mrcode mrcode 10279 Nov 11 14:12 .bash_history
-rw-r--r--.  1 mrcode mrcode    18 Aug  8 20:06 .bash_logout
-rw-r--r--.  1 mrcode mrcode   193 Aug  8 20:06 .bash_profile
1
2
3
4
5
6
7
8

别名的定义规则与变量定义规则几乎相同,另外可以取代已经存在的变量名

alias rm='rm -i'
1

root 可以移除(rm)任何数据,所以当使用 rm 的时候需要小心,可以使用上面的别名指令覆盖掉原始的 rm 指令,执行的时候就是执行 rm -i 指令了

[mrcode@study ~]$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias lm='ls -al | more'
alias ls='ls --color=auto'
alias rm='rm -i'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
1
2
3
4
5
6
7
8
9
10
11

在 root 用户下是没有 vi='vim' 的,一般用户会默认添加该别名

想取消别名可以使用 unalias 指令

unalias lm
1

例题:DOS 年代,列出目录与文件用 dir,清除屏幕用 cls,在 linux 如何达到这个效果?

[mrcode@study ~]$ alias cls='clear'
[mrcode@study ~]$ alias dir='ls -l'
1
2

# 历史命令:history

前面提过 bash 有提供指令历史的服务,可以使用 history 来查询曾经下达过的指令

history [n]
history [-c]
history [-raw] histfiles
1
2
3

选项与参数:

  • n:数字,列出最近 n 条命令
  • c:将目前的 shell 中的所有 history 内容全部消除
  • a:将目前新增的 history 指令新增如 histfiles 中,若没有加 histfiles 则预设写入 ~/.bash_history
  • r:将 histfiles 的内容读到目前这个 shell 的 history 记忆中
  • w:将目前的 history 记忆内容写入 histfiles 中

实践与练习

# 范例 1:列出目前内存内的所有 history 记忆
[mrcode@study ~]$ history
    1  cd /root/
    2  sudo
    3  sudo cd /root/
    .... 中间省略
  666  alias 
  667  alias cls='clear'
  668  alias dir='ls -l'
  669  dir
  670  history

# 范例 2:列出们目前最近的 3 条指令
[mrcode@study ~]$ history 3
  669  dir
  670  history
  671  history 3

# 范例 3:like将目前的资料写入 histfile 中
[mrcode@study ~]$ history -w
# 默认情况会将记录记录写入 ~/.bash_history 中
[mrcode@study ~]$ echo ${HISTSIZE}
1000		# 这里不是现实文件中有多少条,而是最大可存储多少条

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

正常情况下历史命令的读取记录是这样的:

  • 当以 bash 登录 Linux 主机后,系统会主动的由家目录的 ~/.bash_history 读取
  • 假设这次登录后,共下达过 100 次命令,等你注销时,系统就会将 101~1100 总共 1000 条记录更新~/.bash_history 中,因为和能存储最大条数 HISTSIZE 有关系,前面的序号会增加,但是总存储条数只有 HISTSIZE 条
  • 也可以使用 history -w 强制写入

history 指令不只是提供了查询历史记录而已,还可以利用相关命令来执行指令,如下

# 执行第几条命令,这里 number 是数值序号
[mrcode@study ~]$ !number
# 由最近的指令向前搜索指令开头为 command 的哪个指令,并执行
[mrcode@study ~]$ !command
# 执行上一个指令(相当于按 ↑ 后,再按 Enter)
[mrcode@study ~]$ !!

# 使用范例
[mrcode@study ~]$ history 4
  681  man rm
  682  alias
  683  man history
  684  history 4
[mrcode@study ~]$  !681		  # 执行第 681 条指令
 man rm			# 这里会显示具体执行的指令是什么
[mrcode@study ~]$ !!				# 执行上一个指令
 man rm
[mrcode@study ~]$ !al				# 从最新的历史指令开始搜索 al 开头的指令并执行他
alias

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

虽然好用,但是需要小心安全问题,尤其是 root 的历史记录,这是黑客的最爱。另外使用 history 配合 ! 曾经使用过的指令下达是很有效率的一个指令下达方式

# 同一账户同时多次登录的 history 写入问题

常常会同时开几个 bash 窗口,这些 bash 的身份都是 root。这样会有 ~/.bash_history的写入问题吗?

自动写入的条件是注销 bash 时,自动写入,那么最后一个被注销的 bash 窗口中的历史记录会存下来,如果记录大于了 1000 的话,后注销的会覆盖前面先注销的(会有同时注销的情况导致错乱的吗?书上没有说)

由于多重登录有这样的问题,很多朋友都习惯单一 bash 登录,再用后续要讲解的 「工作控制 job control 来切换不同的工作」,这样才能将所有曾经下达过的指令记录下来,也方便未来系统管理员进行指令的 debug

# 无法记录时间

history 有一个问题就是无法记录指令下达时间。按序号记录的,但是没有记录时间。如果有兴趣,其实可以通过 ~/.bash_logout 来进行 history 的记录,并加上 date 来增加时间参数(后续的情景模拟题中会讲到怎么做)

TIP

有一种情况就是,想不要别人翻阅你的历史记录的话,可以使用 history -c;history -w 强迫清除并立即写入文件来清空历史记录