第10章 shell基础知识
shell脚本在日常的linux系统管理工作中是必不可少的,如果不会写shell脚本,你就不算是一个合格的管理员。
11.1 什么是shell
shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。实际上,在shell和计算机硬件之间还有一层东西——系统内核。用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。
Red Hat/CentOS发行版默认安装的shell版本是bash(Bourne Again Shell),它是sh(Bourne Shell)的增强版本。
10.1.1记录历史命令
我们执行过的命令linux都会记录,预设可以记录1000条命令。这些命令保存在用户的家目录的.bash_history文件中。但需要注意,只有当用户正常退出当前shell时,在当前shell中运行的命令才会保存至.bash_history文件中。
!是与命令历史有关的一个特殊字符,常用应用有3个。
!!:连续两个!表示执行上一条命令
!n:表示执行历史命令中的第几条命令
!字符串(字符串大于等于1):表示执行历史命令中最近一次以字符串开头的命令
10.1.2 命令和文件名补全
Tab键可以补全一个命令、路径、或者一个文件名。连续按两次tab键,系统则会把所有的命令或者文件名都列出来。
10.1.3 别名
alias是bash特有的功能之一,我们可以通过alias把一个常用的并且很长的指令另外取一个简单易记的名字。如果不想用了,可以使用unalias命令解除别名功能。直接执行alias命令,会看到目前系统预设的别名。
自定义别名的格式:
alias [命令别名]=[‘具体的命令’]
10.1.4 通配符
在bash下,可以使用*匹配零个或多个字符,用?匹配一个字符。
10.1.5 输入/输出重定向
输入重定向用于改变命令的输入,输出重定向用于改变命令的输出。输出重定向更常用,它经常用于将命令的结果输入到文件中,而不是屏幕上。输入重定向的命令是<,输出重定向的命令是>,错误重定向的命令是2>以及追加重定向的命令是>>。
10.1.6 管道符
|用于将前一个指令的输出作为后一个指令的输入。
实例1
命令:
cat /etc/passwd | wc -l
解释:
查看/etc/passwd的行数
10.1.7 作业控制
当进行进程时,你可以使它暂停(按Ctrl+Z组合键),然后使用fg(foreground的简写)命令恢复它,或是利用bf(background的简写)命令使它到后台运行。此外,你也可以使它终止(按Ctrl+C组合键)。
使用vi命令编辑test1.txt,随便输入一些内容,按Esc键后,使用Ctrl+Z组合键暂停任务。此时提示test1.txt已经停止了,然后使用fg命令恢复它,此时又进入刚才的vi窗口了。再次使其暂停,然后输入jobs,可以看到被暂停或者在后台运行的任务。如果想把暂停的任务放在后台重新运行,就是用bg命令。多个被暂停的任务会有编号,使用jobs命令可以看到两个人物,使用bg命令或者fg命令时,则需要在后面加上编号。
如何关掉在后台运行的任务呢?如果你没有推出刚才的shell,那么应该先使用命令fg编号把任务调到前台,然后Ctrl+C组合键结束任务。另一种情况,关闭当前的shell,再次打开另一个shell时,使用jobs命令并不会显示在后台运行或者被暂停的任务。要想关闭这些任务,则需要先知道它们的pid。使用&把任务放到后台运行时,会显示pid信息。如果忘掉这个pid,还可以使用ps aux命令找到那个进程。如果想结束该进程,需要使用kill命令。kill命令很简单,直接在后面加pid即可。如果遇到结束不了的进程,可以在kill后面加一个选项,即kill -9 [pid]。
10.2 变量
环境变量PATH,它是shell预设的一个变量。通常,shell预设的变量都是大写的。变量就是使用一个较简单的字符串来代替某些具有特殊意义的设定以及数据。就拿PATH来讲,这个PATH就代替了所有常用命令的绝对路径的设定。有了PATH这个变量,我们运行某个命令时,就不需要再输入全局路径,直接输入命令名即可。
实例1
10.2.1 命令env
使用env命令,可列出系统预设的全部系统变量。
登陆不同的用户,这些环境变量的值也不同。
HOSTNAME:表示主机名称
SHELL:当前用户的shell类型
HISTSIZE:历史记录数
MAIL:当前用户的邮件存放目录
PATH:该变量决定了shell将到哪些目录中寻找命令或者程序
PWD:当前目录
LANG:这是与语言相关的环境变量,多语言环境可以修改此环境变量
HOME:当前用户的家目录
LOGNAME:当前用户的登录名
env命令显示的变量只是环境变量,系统预设的变量还有很多,可以使用set命令把系统预设的全部变量都显示出来。
10.2.2 set命令
set命令不仅可以显示系统预设的变量,也可以显示用户自定义的变量。
虽然可以自定义变量,但是该变量只能在当前shell中生效。使用bash命令可以再打开一个shell,此时先前设置的变量已经不存在了,退出当前的shell回到原来的bash,设定的变量还在。
想让设置的变量环境一直有效的两种情况如下:
情况一:
允许系统内所有用户登录后都能使用改变量。具体方法:在/etc/profile文件的最后一行加入export myname=Aming,然后运行source /etc/profile就可以生效了。此时再运行bash或者切换到其他账户就可以看到效果了。
情况二:
仅允许当前用户使用该变量。具体方法:再用户主目录下的.bashrc文件的最后一行加入export myname=Aming,然后运行source /etc/profile就可以生效了。此时再运行bash就可以看到效果了。
这里source的作用是将目前设定的配置刷新,即不用注销再登陆也能生效。
在linux下自定义设置变量的规则如下:
1、设定变量的格式为a=b,其中a为变量名,b为变量的内容,等号两边不能有空格。
2、变量名只能由字母、数字以及下划线组成,而且不能以数字开头。
3、当变量内容带有特殊符号(如空格)时,需要加上单引号。
4、当变量内容中本身带有单引号时,此时就需要加双引号了。
5、当变量内容需要用到其他命令时,运行结果则可以使用反引号。
变量内容可以累加其他变量的内容,但需要加上双引号。如果把双引号错加为单引号,则不能得到想要的内容。
双引号和单引号的区别:使用双引号时,不会取消双引号中特殊符号本身的作用,而使用单引号时,里面的特殊字符将全部失去其本身的作用。
如在当前shell中运行bash命令,则会进入一个新的shell,这个shell就是原来shell的子shell。用pstree命令可以查看,如果pstree命令没有安装,可以通过yum install –y psmisc命令安装。pstree会把linux系统中的所有进程以树形结构显示出来。在父shell中设定变量后,进入子shell时,该变量是不会生效的。如果想让这个变量在子shell中生效,则要用到export指令。
其实export的作用就是声明一下这个变量,让该shell的子shell也知道该变量的值。设置变量之后,如果想取消这个变量,只要输入unset 变量名即可。
10.3 系统环境变量与个人环境变量的配置文件
10.3.1 /etc/profile:这个文件预设了几个重要的变量,例如PATH、USER、LOGNAME、MAIL、INPUTRC、HOSTNAME、HISTSIZE、umask
10.3.2 /etc/bashrc:这个文件主要预设umask以及PS1.这个PS1就是我们在输入命令时前面的那串字符。
\u指用户,\h指主机名,\W指当前目录,\$指字符#(如果是普通目录,则显示$),上面两个是系统文件,各个用户的主目录下还有以下几个隐藏文件。
10.3.3 .bash_profile:该文件定义了用户的个人化路径与环境变量的文件名称。每个用户都可以使用该文件输入专属于自己的shell信息,当用户登录时,该文件仅仅执行一次。
10.3.4 .bashrc:该文件包含专属于自己的shell的bash信息,当登录或每次打开新的shell时,该文件会被读取。
10.3.5 .bash_history:该文件用于记录命令历史。
10.3.6 .bash_logout:当退出shell时,会执行该文件。你可以将一些清理的工作放到这个文件中。
10.4 linux shell中的特殊符号
10.4.1 *代表零个或多个任意字符
10.4.2 ?代表一个任意的字符
10.4.3 注释符号#
#后面的内容都会被忽略
10.4.4脱义字符\
这个字符会将后面的特殊符号(如*)还原为普通字符。
10.4.5 管道符
它的作用是将前面命令的输出作为后面命令的输入,这里提到的前面的命令并不是所有的命令都可以,一般针对文档操作的命令比较常用。例如cat、less、head、tail、grep、cut、sort、wc、uniq、tee、tr、split、sed、awk等,其中grep、sed、awk是正则表达式必须掌握的工具。
10.4.6 命令cut
cut命令用来截取某一字段,其格式为
cut –d ‘分隔符’ [-cf] n,这里的n是数字。该命令有如下选项:
-d:后面跟分隔符,分隔符要用单引号括起来。
-f:后面接的是第几块区域。
-c:后面接的是第几个字符。
实例1
命令:
head -n5 /etc/passwd | cut -d ':' -f 1
解释:
截取/etc/passwd的第一段
-d选项后面加冒号作为分隔符,-f 1表示截取第一段,-f和1之间的空格可有可无。
实例2
-c选项后可以是1个数字n,也可以是一个区间n1-n2,还可以是多个数字n1、n2和 n3。
命令:
head -n2 /etc/passwd | cut -c1-10
解释:
截取/etc/passwd前两句的第1到10个字符
实例3
命令:
head -n2 /etc/passwd | cut -c1,3,10
解释:
截取/etc/passwd前两句的第1,3,10三个字符
10.4.7 命令sort
sort命令用作排序,其格式为:
sort [-t 分隔符] [-kn1,n2] [-nru],这里的n1和n2指的是数字,其他选项的含义如下。
-t:后面跟分隔符,作用跟cut的-d选项一样
-n:表示使用纯数字排序。
-r:表示反向排序。
-u:表示去重复。
-kn1,n2:表示由n1区间排序到n2区间,可以只写-kn1,即对n1字段排序。
如果sort不加任何选项,则从首字符向后依次按ASCII码值进行比较,最后将它们按升序输出。
实例1
命令:
head -n5 /etc/passwd | sort
解释:
/etc/passwd的前5行从首字符向后依次按ASCII码值进行比较,最后将它们按升序输出。
实例2
命令:
head -n5 /etc/passwd | sort -t: -k3 –n
解释:
/etc/passwd的前5行,以冒号为分隔符,按纯数字对第3个区域进行排序。
实例3
-k选项后面跟数字n1和n2表示对第n1和n2区域内的字符串排序,-r选项则表示反向排序。
命令:
head -n5 /etc/passwd | sort -t: -k3,5 -r
解释:
/etc/passwd的前5行,以冒号为分隔符,对第3到第5区域内的字符串进行反向排序
10.4.8 命令wc
wc用于统计文档的行数、字符数或词数。该命令的常用选项有-l(统计行数)、-m(统计字符数)、-w(统计词数)
10.4.9 命令uniq
命令uniq用来删除重复的行,该命令只有-c选项常用,它表示统计重复的行数,并把行数写在前面。
实例1
使用uniq前,必须先给文件排序,否则不管用
命令:
sort testb.txt | uniq -c
解释:
给testb.txt排序,然后统计重复的行数
10.4.10 命令tee
命令tee后面跟文件名,其作用类似于重定向>,但它比重定向多一个功能,即把文件写入后面所跟的文件时,还显示在屏幕上。该命令常用于管道符|后。
实例1
命令:
解释:
将aaaaaaaa添加到testb.txt中并在屏幕上显示出来
10.4.11 命令tr
tr命令用于替换字符,常用来处理文档中出现的特殊符号,如DOS文档中出现的符号^M。该命令常用的选项有以下两个。
-d:表示删除某个字符,后面跟要删除的字符
-s:表示删除重复的字符
实例1
tr命令常用于把小写字母变成大写字母,如tr ‘[a-z]’ ‘[A-Z]’。
命令:
head -n2 /etc/passwd | tr '[a-z]' '[A-Z]'
解释:
把/etc/passwd的前两行小写变大写
实例2
tr命令还可以替换一个字符
命令:
grep ‘root’ /etc/passwd | tr ‘r’ ‘R’
解释:
把/etc/passwd中有root字符串的行找出来,并把r编程R。
注:不过,替换、删除以及去重复等操作都是针对一个字符来讲的,有一定的局限性。如果是针对一个字符串,就不能用了,这个命令只需要简单了解一下即可。
10.4.12 命令split
split命令用于切割文档,常用的选项为-b和-l。
-b:表示依据大小来分割文档,单位为byte。
实例1
命令:
解释:
以500byte为单位来分割/etc/passwd文档
注:如果split不指定目标文件名,则会以xaa、xab……这样的文件名来存取切割后的文件。当然,我们也可以指定目标文件名。
实例2
命令:
解释:
以500byte为单位来分割/etc/passwd文档,并制定文件名为123
-l:表示依据行数来分割。
实例3
命令:
解释:
以10行来分割passwd
10.4.13 特殊符号$
符号$可以用作变量前面的标识符,还可以和!结合起来使用。
实例1
命令:
解释:
!$表示上条命令中的最后一个变量。
10.4.14 特殊符号;
如果想要在一行中输入两个以上的命令,需要在命令之间加;。
实例1
命令:
10.4.15 特殊符号~
符号~表示用户的家目录,root用户的家目录是/root,普通用户则是/home/username。
实例1
命令:
10.4.16 特殊符号&
如果想把一条命令放在后台执行,则需要加上符号&。它通常用于命令运行时间较长的情况。
实例1:
命令:
10.4.17 重定向符号
重定向符号>和>>,表示取代和追加的意思。当我们运行一个命令报错时,报错信息会输出到当前屏幕。如果想重定向到一个文本,则要用重定向符号2>或者2>>,它们分别表示错误重定向和错误追加重定向。
实例1
命令:
10.4.18 中括号[]
中括号内为字符组合,代表字符组合中的任意一个,可以是一个范围(1-3,a-z)。
实例1
命令:
10.4.19 特殊符号&&和||
用于多条命令中间的特殊符号有;、&&、||。
command1; command2
command1&&command2
command1|| command2
使用;时,不管command1是否执行成功,都会执行command2。
使用&&时,只用command1执行成功,command2才会执行,否则command2不执行。
使用||时,command1执行成功后则command2不执行,否则执行command2,即command1和command2中总有一条命令去执行。
只有当ls test2成功执行后,才会执行touch test2。因为test2不存在,所以ls test2没有执行成功,所有&&后面的touch test2并没有执行。
如ls test2执行不成功,则会执行touch test2。因为test2不存在,所以ls test2没有执行成功,转而执行||后面的touch test2,所以增加了test2这个文件。