2.5 Shell实用功能
Shell的实用功能主要有命令行自动补全、命令历史记录、命令排列、命令替换、命令别名、文件名匹配和管道。
2.5.1 命令行自动补全
在Linux系统中,有太多的命令和文件名称需要记忆,使用命令行补全功能可以快速地写出文件名和命令名。
如果需要快速地从当前所在的目录跳转到/usr/src/kernels/目录,可以执行以下操作。
[root@rhel ~]# cd /u<Tab>/sr<Tab>/k<Tab>
<Tab>是按[Tab]键的意思,使用[Tab]键也称为命令行自动补全,这在平常应用中是不可缺少的。
让我们仔细看看这个例子。
[root@rhel ~]# cd /u<Tab>
扩展成了“cd /usr/”,再按[Tab]键,如下所示,扩展为“cd /usr/src/”。
[root@rhel ~]# cd /u<Tab>/sr<Tab>
因此,使用[Tab]键可以很方便地根据前几个字母来查找匹配的文件或子目录。
2.5.2 命令历史记录
在操作Linux系统的时候,每一个操作的命令都会被记录到命令历史中,在以后可以通过命令历史查看和使用以前操作的命令。
1.和命令历史有关的变量
bash启动的时候会读取~/.bash_history文件,并将其载入到内存中。$HISTFILE变量用于设置~/.bash_history文件,bash退出时也会把内存中的历史记录回写到~/.bash_history文件中。
例2.15:显示$HISTFILE变量的值。
[root@rhel ~]# echo $HISTFILE
/root/.bash_history
在/etc/profile 文件文件中,默认定义了1000个命令历史记录,如下所示。
[root@rhel ~]# cat /etc/profile |grep HISTSIZE
HISTSIZE=1000
下面介绍一下$HISTSIZE和$HISTFILESIZE变量。
● $HISTSIZE:设置bash会话期间命令历史包含的命令数量;
● $HISTFILESIZE:设置历史文件中实际存储的命令数量。
例2.16:显示$HISTSIZE和$HISTFILESIZE变量的值。
[root@rhel ~]# echo $HISTSIZE
1000
[root@rhel ~]# echo $HISTFILESIZE
1000
2.使用命令历史
使用history命令可以查看命令历史记录,每一条命令前面都会有一个序列号标示。
命令语法:
history [选项]
命令中各选项的含义如表2.13所示。
表2.13 history命令选项的含义
在Linux系统中使用命令历史的举例如表2.14所示。
表2.14 使用命令历史的举例
通过表2.15所示的快捷键可以非常方便地搜索历史命令。
表2.15 搜索历史命令
例2.17:使用命令历史记录功能键。
[root@rhel ~]# mkdir /root/aaa
//创建目录/root/aaa
[root@rhel ~]# cd !$
cd /root/aaa
//!$是指重复前一个命令最后的参数,参数是/root/aaa
[root@rhel aaa]# pwd
/root/aaa
//显示用户当前目录是/root/aaa
例2.18:查看命令历史记录。
[root@rhel ~]# history
//显示过去曾经输入过的命令,只有两列信息:编号和命令
例2.19:显示执行过的前两条命令。
[root@rhel ~]# history 2
//在这里使用history +2和history 2命令起到的效果一样
例2.20:查看/root/.bash_history文件。
[root@rhel ~]# cat /root/.bash_history
例2.21:将当前的历史命令写入.bash_history文件。
[root@rhel ~]# history-w
例2.22:将目前新增的 history 历史命令写入.bash_history文件。
[root@rhel ~]# history-a
例2.23:清空命令历史记录。
[root@rhel ~]# history-c
//清空命令历史记录以后,再次使用history命令已经无法查看以前的命令历史
2.5.3 命令排列
如果希望一次执行多个命令,Shell允许在不同的命令之间放上特殊的排列字符。命令排列可以使用两种排列字符:“;”和“&&”。
1.使用“;”
使用“;”命令时先执行命令1,不管命令1是否出错,接下来就执行命令2。
命令语法:
命令1;命令2
例2.24:使用排列命令“;”同时执行两个命令。
[root@rhel ~]# ls /boot;du-hs /root
config-3.10.0-327.el7.x86_64
extlinux
grub2
initramfs-0-rescue-695707d564a94beba0e784062566b7e0.img
initramfs-3.10.0-327.el7.x86_64.img
initramfs-3.10.0-327.el7.x86_64kdump.img
initrd-plymouth.img
symvers-3.10.0-327.el7.x86_64.gz
System.map-3.10.0-327.el7.x86_64
vmlinuz-0-rescue-695707d564a94beba0e784062566b7e0
vmlinuz-3.10.0-327.el7.x86_64
4.4 M /root
//先在屏幕上列出/boot目录中的所有内容,然后列出目录/root及其子目录所占用的磁盘空间大小
2.使用“&&”
使用“&&”命令时,只有当命令1正确运行完毕后,才能执行命令2 。
命令语法:
命令1&&命令2
例2.25:使用排列命令“&&”同时执行两个命令。
[root@rhel ~]# ls-a /root/bogusdir&&du-sh
ls: 无法访问/root/bogusdir: 没有那个文件或目录
//将返回“ls: 无法访问/root/bogusdir: 没有那个文件或目录”,而“du-sh”命令根本没有运行,因为第一个命令都没有成功执行
2.5.4 命令替换
在Linux系统中,Shell命令的参数可以由另外一个命令的结果来替代,这种操作称为命令替换。
命令替换可以使用两种替换字符:“$( )”和“``”。
1.使用“$( )”
命令语法:
命令1 $(命令2)
下面讲解一个例子。
结束一个名为less的进程前先得用命令pidof找出相应的进程号,然后以这个进程号为参数,运行kill命令,这样就可以结束less进程,使用以下命令。
[root@rhel ~]# pidof less
7552
//less进程号为7552
[root@rhel ~]# kill-9 7552
//结束进程号为7552的进程(也就是less进程)
例2.26:使用命令替换功能结束less进程。
[root@rhel ~]# kill-9 $(pidof less)
// pidof less命令的输出7552作为命令kill-9的参数,然后就可以结束该进程了
2.使用“``”
除了可以使用“$()”之外,还可以使用后引号“'”(位于Tab键上面那个键)。
命令语法:
命令1 '命令2'
这样虽然可以减少输入,但可读性差,而且很容易和没有替换功能的一般单引号混淆。
例2.27:使用命令替换功能结束less进程。
[root@rhel ~]# kill-9 'pidof less'
2.5.5 命令别名
在需要执行某一个非常长的命令时,所有的命令以及命令的选项、参数都要一一输入,很枯燥也容易出现错误。可以为常用命令定义快捷方式,这些快捷方式可以用比较简单的命令别名来定义。
1.创建别名
使用alias命令可以为命令定义别名。如果命令中有空格的话,就需要使用双引号(比如在命令与选项之间就有空格)。
命令语法:
alias [别名]=[需要定义别名的命令]
例如,使用下面的命令查看/boot目录的内容。
[root@rhel ~]# ls /boot
显然,如果每次需要查看/boot目录的内容都要输入这样的命令,会非常麻烦,因此可以定义别名。
例2.28:为ls /boot命令创建别名ok。
[root@rhel ~]# alias ok="ls /boot"
[root@rhel ~]# ok
config-3.10.0-327.el7.x86_64
extlinux
grub2
initramfs-0-rescue-695707d564a94beba0e784062566b7e0.img
initramfs-3.10.0-327.el7.x86_64.img
initramfs-3.10.0-327.el7.x86_64kdump.img
initrd-plymouth.img
symvers-3.10.0-327.el7.x86_64.gz
System.map-3.10.0-327.el7.x86_64
vmlinuz-0-rescue-695707d564a94beba0e784062566b7e0
vmlinuz-3.10.0-327.el7.x86_64
//在终端中输入别名ok就可以查看/boot目录的内容
例2.29:查看系统中所有的别名。
[root@rhel ~]# alias
alias cp='cp-i'
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 ls='ls--color=auto'
alias mv='mv-i'
alias ok='ls /boot'
alias rm='rm-i'
alias which='alias | /usr/bin/which--tty-only--read-alias--show-dot--show-tilde'
//有些别名(比如cp、ll、ls、mv、rm、which)是系统定义的,有些别名(比如ok)是用户定义的
2.取消别名
当用户需要取消别名的定义时,可以使用unalias命令。
命令语法:
unalias [别名]
例2.30:取消之前定义的别名ok。
[root@rhel ~]# unalias ok
[root@rhel ~]# ok
bash: ok: 未找到命令...
//取消别名之后不能使用别名ok了
在重新启动计算机系统以及关闭终端以后,定义的别名会失效。若系统中有一个命令,同时定义了一个与其同名的别名,则别名将优先于系统中原有的命令而执行。
注意:
如果希望重新启动计算机系统以及关闭终端以后,定义的别名仍旧生效,可以编辑/etc/bashrc(针对系统中所有用户)或$HOME/.bashrc(针对某一个指定用户,$HOME代表用户主目录)文件,将别名定义命令写到这两个文件中。
2.5.6 文件名匹配
文件名匹配使得用户不必一一写出文件名称就可以指定多个文件。这将用到一些特殊的字符,称之为通配符。
1.通配符“*”
“*”可匹配一个或多个字符。假设想用rm命令删除当前目录下所有以字符串“.bak”结尾的文件,除了在rm命令后面写上所有文件名作为参数,还可以使用通配符“*”,使用以下命令。
[root@rhel ~]# rm *.bak
在本例中,告诉Shell将命令rm的参数扩展到所有以“.bak”结尾的文件,Shell就将扩展后的参数告诉rm命令。Shell在命令执行前,将读取并解释命令行。
假如当前目录下,包含文件124.bak、346.bak和583.bak。如果只想保留文件583.bak,将其余两个文件删除,可以使用以下命令。
[root@rhel ~]# rm *4*.bak
Shell就将“*4*.bak”扩展成所有含“4”并以“.bak”结尾的字符串。
2.通配符“?”
第二个通配符是“?”。在匹配时,一个问号只能代表一个字符。为了示范其用途,我们在上例的假设中另外再添加311.bak和abcd.text两个新文件。现在,列出所有在“.”后有4个字符的文件,使用以下命令。
[root@rhel ~]# ls *.????
abcd.text
2.5.7 管道
Linux系统的理念是汇集许多小程序,每个程序都有特殊的专长。复杂的任务不是由大型软件完成,而是运用Shell 的机制,组合许多小程序共同完成。管道就在其中发挥着重要的作用,它可以将某个命令的输出信息当作某个命令的输入,由管道符号“|”来标识。
命令语法:
[命令1]|[ 命令2]|[ 命令3]
例2.31:使用简单的管道。
[root@rhel ~]# ls /etc|more
abrt
adjtime
akonadi
aliases
aliases.db
alsa
...(省略)
cgconfig.conf
cgconfig.d
cgrules.conf
cgsnapshot_blacklist.conf
chkconfig.d
chrony.conf
--More-
//命令ls /etc显示/etc目录的内容,命令more是分页显示内容
例2.32:使用复杂的管道。
[root@rhel ~]# rpm-qa|grep a|more
//命令rpm-qa显示已经安装在系统上的RPM包,命令grep a是过滤软件包,命令more是分页显示这些信息