一、shell 基础知识
1. 什么是shell
shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。实际上,在shell和计 算机硬件之间还有一层东西——系统内核。如果把计算机硬件比作一个人的躯体,那系统内核就是人 的大脑。至于shell,把它比作人的五官似乎更贴切些。言归正传,用户直接面对的不是计算机硬件而 是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。
1.1 记录命令历史
!是与命令历史有关的一个特殊字符,该字符常用的应用有以下3个。
- !!:连续两个!表示执行上一条指令。示例命令如下:
- !n:这里的n是数字,表示执行命令历史中的第n条指令。例如,!1002表示执行命令历史中的第1002个命令,如下所示:
- !字符串(字符串大于等于1):例如!pw表示执行命令历史中最近一次以pw开头的命令。示例代码如下:
1.2 命令和文件名补全
按tab键可以帮我们补全一个指令、一个路径或者一个文件名。连续按两次tab键,系统则会把所有的命令或者文件名都列出来。
1.3 别名
前面的章节中也曾提到过alias,它也是bash所特有的功能之一。我们可以通过alias把一个常用的并且很长的指令另取名为一个简单易记的指令。如果不想用了,还可以使用unalias命令解除别名功能。
直接执行alias命令,会看到目前系统预设的别名,如下所示:
你也可以自定义命令的别名,其格式为 alias [命令别名]=[‘具体的命令’],示例命令如下:
1.4 通配符
在bash下,可以使用*来匹配零个或多个字符,用?匹配一个字符。示例命令如下:
1.5 输入/输出重定向
输入重定向用于改变命令的输入,输出重定向用于改变命令的输出。输出重定向更为常用,它经常用于将命令的结果输入到文件中,而不是屏幕上。输入重定向的命令是<,输出重定向的命令是>。
另外,还有错误重定向命令 2> 以及追加重定向命令>>,示例命令如下:
1.6 管道符
管道符 | ,它用于将前一个指令的输出作为后一个指令的输入,如下所示:
1.7 作业控制
当运行进程时,你可以使它暂停(按Ctrl+Z组合键),然后使用fg(foreground的简写)命令恢复它,或是利用bg(background的简写)命令使它到后台运行。此外,你也可以使它终止(按Ctrl+C组合键)。示例命令如下:
使用vi命令编辑test1.txt,随便输入一些内容,按Esc键后,使用Ctrl+Z组合键暂停任务,如下所示:
此时提示vi test1.txt已经停止了,然后使用fg命令恢复它,此时又进入刚才的vi窗口了。再次使其暂停,然后输入jobs,可以看到被暂停或者在后台运行的任务,如下所示:
如果想把暂停的任务放在后台重新运行,就使用bg命令,如下所示:
2. 变量
变量PATH,它是shell预设的一个变量。通常,shel预设的变量都是大写的。变量就是使用一个较简单的字符串来替代某些具有特殊意义的设定以及数据。就拿PATH来讲,这个PATH就代替了所有常用命令的绝对路径的设定。有了PATH这个变量,我们运行某个命令时,就不再需要输入全局路径,直接输入命令名即可。
你可以使用echo命令显示变量的值,如下所示:
除此之外还有:ENV、HISTSIZE、HOSTNAME、HOSTTYPE、MAIL等等
2.1 命令 env
使用env命令,可列出系统预设的全部系统变量,如下所示:
登录不同的用户,这些环境变量的值也不同。当前显示的是root账户的环境变量。下面简单介绍一下常见的环境变量。
-
HOSTNAME:表示主机的名称。
-
SHELL:表示当前用户的shell类型。
-
HISTSIZE:表示历史记录数。
-
MAIL:表示当前用户的邮件存放目录。
-
PATH:该变量决定了shell将到哪些目录中寻找命令或程序。
-
PWD:表示当前目录。
-
LANG:这是与语言相关的环境变量,多语言环境可以修改此环境变量。
-
HOME:表示当前用户的家目录。
-
LOGNAME:表示当前用户的登录名。
2.2 命令set
set命令和env命令类似,也可以输出环境变量,如下所示:
set 命令不仅可以显示系统预设的变量,也可以显示用户自定义的变量,例如:
虽然可以自定义变量,但该变量只能在当前shell中生效,如下所示:
使用bash命令可以再打开一个shell,此时先前设置的myname变量已经不存在了,退出当前shell回到原来的shell,myname变量还在。如果想让设置的环境变量一直生效,该怎么做呢?这分以下两种情况:
- 允许系统内所有用户登录后都能使用该变量。具体的操作方法是:在/etc/profile文件的最后一行加入export myname=Aming,然后运行source/etc/profile就可以生效了。此时再运行bash命令或者切换到其他账户(如su-test)就可以看到效果。如下所示:
- 仅允许当前用户使用该变量。具体的操作方法是:在用户主目录下的.bashrc文件的最后一行加入export myname=Aming,然后运行source.bashrc就可以生效了。这时再登录test账户,myname变量则不会生效了。这里source命令的作用是将目前设定的配置刷新,即不用注销再登录也能生效。
在Linux下设置自定义变量的规则有: - 设定变量的格式为a=b,其中a为变量名,b为变量的内容,等号两边不能有空格。
- 变量名只能由字母、数字以及下划线组成,而且不能以数字开头。
- 当变量内容带有特殊字符(如空格)时,需要加上单引号。示例如下:
3. 系统环境变量与个人环境变量的配置文件
上面讲了很多系统变量,那么在Linux系统中,这些变量存在哪里呢?为什么用户一登录shell就自
动有了这些变量呢?我们先来看看下面几个文件。
- /etc/profile:这个文件预设了几个重要的变量,例如PATH、USER、LOGNAME、MAIL、INPUTRC、
HOSTNAME、HISTSIZE、umask等。 - /etc/bashre:这个文件主要预设umask以及PS1。这个PS1就是我们在输入命令时前面的那串字符。
例如,Linux系统的PS1就是[rootelocalhost~]#,我们不妨看一下PS1的值,如下所示:
其中,u指用户,h指主机名,\W指当前目录,$指字符#(如果是普通用户,则显示为$)。
除了以上两个系统级别的配置文件外,每个用户的主目录下还有以下几个隐藏文件。
- .bash_profile:该文件定义了用户的个人化路径与环境变量的文件名称。每个用户都可使用
该文件输入专属于自己的shell信息,当用户登录时,该文件仅仅执行一次。 - .bashre:该文件包含专属于自己的shell的bash信息,当登录或每次打开新的shell时,该文件
会被读取。例如,你可以将用户自定义的别名或者自定义变量写到这个文件中。 - .bash history:该文件用于记录命令历史。
- .bash_logout:当退出shell时,会执行该文件。你可以将一些清理的工作放到这个文件中。
4. Linux shell 中的特殊符号
在学习Linux的过程中,也许你已经接触过某个特殊符号,例如*,它是一个通配符,代表零个或多个字符或数字。下面就介绍一下常用的特殊字符。
4.1 *代表零个或多个任意字符
4.2 ?只代表一个任意的字符
4.3 注释符号
4.4 脱义字符 \
这个字符会将后面的特殊符号(如*)还原为普通字符。用法如下:
4.5 再说管道符 |
这个字符前面曾多次出现过,它的作用是将前面命令的输出作为后面命令的输入。这里提到的后面的命令,并不是所有的命令都可以的,一般针对文档操作的命令比较常用。例如cat、less、head、tail、grep、cut、sort、wc、uniq、tee、tr、split、sed、ak等,其中grep、sed和ak是正则表达式必须掌握的工具,在第11章中会详细介绍。管道符的用法如下:
在上例中,wc -l 用来计算一个文档有多少行。这里列出了很多陌生的命令,这些命令在日常的文档处理工作中非常实用,所以需要先简单介绍一下它们如果你记不住。
4.6 命令 cut
cut命令用来截取某一个字段,其格式为 cut -d '分隔字符’ [-cf] n,这里的n是数字。该命令有如下几个可用选项。
- -d:后面跟分隔字符,分隔字符要用单引号括起来。
- -c:后面接的是第几个字符。
- -f:后面接的是第几个区块。
cut 命令的用法如下:
-d选项后面加冒号作为分隔字符,-f1表示截取第一段,-f 和 1 之间的空格可有可无。示例命令如下:
-c 选项后面可以是1个数字n,也可以是一个区间n1-n2,还可以是多个数字n1、n2和n3。示例命令如下:
4.7 命令 sort
sort命令用做排序,其格式为 sort [-t 分隔符] [-kn1,n2] [-nru],这里n1和n2指的是数字,其他选项的含义如下。
- -t:后面跟分隔字符,作用跟cut的-d选项一样。
- -n:表示使用纯数字排序。
- -r:表示反向排序。
- -u:表示去重复。
- -km1,n2:表示由n1区间排序到n2区间,可以只写-kn1,即对nm字段排序。
如果sort不加任何选项,则从首字符向后依次按ASCII码值进行比较,最后将它们按升序输出。示例命令如下:
-t 选项后面跟分隔符,-k 选项后面跟单个数字表示对第几个区域的字符串排序,-n 选项则表示使用纯数字排序。示例命令如下:
-k 选项后面跟数字 n1和 n2表示对第 n1和n2区域内的字符串排序,-r 选项则表示反向排序。示例命令如下:
4.8 命令 wc
wc命令用于统计文档的行数、字符数或词数。该命令的常用选项有 -l(统计行数)、-m(统计字符数)和-w(统计词数)。示例命令如下:
如果wc不跟任何选项,直接跟文档,则会把行数、词数和字符数依次输出。
4.9 命令 uniq
uniq命令用来删除重复的行,该命令只有-c选项比较常用,它表示统计重复的行数,并把行数写在前面。我们先来编写一个文件,示例命令如下:
使用uniq前,必须先给文件排序,否则不管用,如下:
经测试不加 -u选项依然可以去重复!
4.10 命令 tee
tee命令后面跟文件名,其作用类似于重定向 >,但它比重定向多一个功能,即把文件写入后面所跟的文件时,还显示在屏幕上。该命令常用于管道符|后。示例命令如下:
这里我依然采取与上个命令同一文件3.txt,使用tee命令重定向后原有的内容不会再存在!(即重定向的意思)
4.11 命令 tr
tr命令用于替换字符,常用来处理文档中出现的特殊符号,如DOS文档中出现的符号M。该命令常用的选项有以下两个。
- -d:表示删除某个字符,后面跟要删除的字符。
- -s:表示删除重复的字符。
tr命令常用于把小写字母变成大写字母,如tr ‘[a-z]’ ‘[A-Z]’。示例命令如下:
tr命令还可以替换一个字符,示例命令如下:
4.12 命令 split
split命令用于切割文档,常用的选项为-b和-1。
- -b:表示依据大小来分割文档,单位为byte,示例命令如下:
也可以指定目标文件名,如下:
- -l:表示依据行数来分割文档,示例命令如下:
4.13 特殊符号$
符号可以用作变量前面的标识符,还可以和!结合起来使用。示例命令如下:
4.14 特殊符号;
通常,我们都是在一行中输入一个命令,然后回车就运行了。如果想在一行中运行两个或两个以上的命令,需要在命令之间加符号;。示例命令如下:
4.15 特殊符号 ~
符号表示用户的家目录,root用户的家目录是/root,普通用户则是/home/usermame。示例命令如下:
4.16 特殊符号 &
如果想把一条命令放到后台执行,则需要加上符号&,它通常用于命令运行时间较长的情况。比如,可以用在 sleep后,如下所示:
经测试:sleep 30的意思是睡眠30秒,不加&选项就是在这30秒不可执行其他操作,除非你使用CTRL + C退出,加了&就是在后台进行,可以进行操作!
4.17 重定向符号 >、>>、2>和2>>
当我们运行一个命令报错时,报错信息会输出到当前屏幕。如果想重定向到一个文本,则要用重定向符号2>或者2>>,它们分别表示错误重定向和错误追加重定向。示例命令如下:
4.18 中括号 [ ]
中括号内为字符组合,代表字符组合中的任意一个,可以是一个范围(1-3,a-z),用法如下:
4.19 特殊符号&&和||
前面提到了分号可作为多条命令间的分隔符,其实还有两个可以用于多条命令中间的特殊符号,那就是&&和 ||。下面列出以下几种情况:
- command1 ;command2
- command1 && command2
- command1 || command2
使用;时,不管command1是否执行成功,都会执行commandz。
使用&时,只有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这个文件。
二、课后习题
(1)请设置环境变量HISTSIZE,使其能够保存10000条命令历史。
答:先进入vi /etc/profile,然后把 HISTSIZE=1000 改为 HISTSIZE=10000即可
(2)如果设置PS1=“[ \u@\h \W]$",为什么显示的结果和我们预想的不一样?如何才能恢复默认设置?
答:使用echo $PS1即可
(3)如何把当前目录下文件的文件名中的小写字母全部替换为大写字母?
答:百度得:for f in ls
; do if echo $f |grep -q ‘[a-z]’; then mv $f echo $f|tr '[a-z]' '[A-Z]'
;fi; done
(4)以:为分隔符,使用sort命令对/etc/passwd文件的第5段排序。
答:如图:
(5)以:为分隔符,使用cut命令截出/etc/passwd的第3段字符。
答:如图
(6)简述这几个文件的作用:/etc/profile、/etc/bashrc、.bashrc和.bash profile。
答:百度得:
/etc/profile : 设置系统全局环境变量和启动程序,当用户登录Linux时,该文件被执行,并从/etc/profile.d目录的配置文件中搜集shell的设置。预设的系统全局变量包括PATH、USER、LOGNAME、MAIL、INPUTRC、HOSTNAME、HISTSIZE、umask等。
/etc/bashrc : 为每一个运行bash shell的用户执行此文件。当bash shell被打开时,该文件被读取。默认情况下,这个文件主要预设umask以及PS1等。
.bash_profile : 定义用户专有的环境变量和启动程序。当用户登录时,该文件仅仅执行一次。 默认情况下,它设置了一些环境变量,执行用户的.bashrc文件。
.bashrc :该文件包含专用于用户的shell的bash信息,当用户登录时以及每次打开新的shell时,该该文件被读取。可以将用户自定义的alias和变量写到这个文件中。
(7)export的作用是什么?
答: export 用来声明变量,可以使声明的变量在子shell中生效
(8)Linux下自定义变量要符合什么样的规则?
答:
1.设定变量的格式为“a=b”, 其中a为变量名,b为变量的内容,等号两边不能有空格;
2.变量名只能由英、数字以及下划线组成,而且不能以数字开头;
3.当变量内容带有特殊字符(如空格)时,需要加上单引号,变量内容中本身带有单引号的情况则使用双引号;
4.如果变量内容中需要用到其他命令运行结果则可以使用反引号;
5.变量内容可以累加其他变量的内容,需要加双引号。
(9)如何把要运行的命令放到后台运行?如何把后台运行的进程调到前台?
答:
1.将运行的命令放到后台运行,可以先按CTRL + Z 让它暂停,然后使用bg命令即可;或者执行命令时在后面添加参数 &即可。
2.将后台运行的进程调到前台,可以输入fg命令即可。
(10)列出当前目录下以test开头的文件和目录。
答:如图
(11)如何把一个命令的输出内容打印到屏幕上,并重定向到一个文件内?
答: 使用tee命令,例如 : cat /etc/passwd | tee 1.txt
(12)假如有个命令很长,如何用一个简单的字符串代替这个复杂的命令呢?请举例说明。
答:如图
(13)如何把一个命令放到后台运行,并将其正确输出和错误输出同时重定向到一个文件内?
答:百度得:
vmstat 1 > /tmp/1.log 2>&1 &
(14)如何按照大小(如10MB)分隔一个大文件?又如何按照行数(如10000行)分隔呢?
答:
- split -b 10M bigfile
- split -l 10000 bigfi
(15)做试验弄清楚;、&&以及||这3个符号的含义。
答:根据上述4.14;4.19操作得出:
; 只是用来分割多个命令,各条命令相互独立运行,没有任何关联性。
&& 只有前面的命令成功执行后,后面的命令才会执行。如果前面的命令执行失败,则忽略后面的命令。
|| 多条命令中只要一条命令执行成功,则忽略后面的命令,否则运行后面的命令。
(16)如果只想让某个用户使用某个变量,如何做?
答:先进入vi /root/.bashrc 增加一行 export v=user1,再 source /root/.bashrc 即可。
(17)使用哪个命令会把系统当中所有的变量以及当前用户定义的自定义变量列出来?
答: set命令