Shell
一、序言
管理整个计算机硬件的是操作系统内核,内核是需要被保护的,所以我们用户一般只能通过shell来和内核通信。Shell只是提供给用户操作系统的一个接口。说点通俗易懂的,能够操作应用程序的接口都可以称为Shell,狭义上的shell指的是命令行方面的软件,广义上的shell则包括图形界面的软件。
二、bash — 狭义上的shell
(一)、bash的优点
命令记忆能力
我们可以使用上下键去找到前后输入的命令,几乎我们所有使用过的命令都被记忆下来了。
记忆命令的文件,一般是在主目录下的.bash_history文件中,
cat ~/.bash_history
可以查看,注意:这个文件是前一次登录以前执行过的命令,这一次登录执行过的命令都被暂存在临时内存中的,当我们注销后才会记录到文件中去。命令与文件补全功能(Tab键的好处)
这个功能能方便我们的操作,而且能保证我们输入的正确性。
命令别名设置功能
设置别名是可以简化我们的命令的,例如:ll ——— ls -l。
执行别名
alias lm='ls -al'
, 以后lm就是代表ls -al。作业控制、前台、后台控制
有利于我们的作业进行的更方便。
程序脚本
可以将我们平时管理系统仓需要执行的连续命令写成一个文件。该文件通过交互进行主机检测功能。
通配符
(二)、bash shell内置命令:type
命令:type [-tpa] name
参数解释:
type不加任何参数的时候,type胡显示出name是外部的命令还是bash的内置命令
-t
file :表示为外部命令
alias :表示为命令为命令别名设置的名称
builtin :表示该命令Wiebash内置的命令
-p 如果后面接的name是外部命令的时候会显示完整文件名
-a 会由path变量定义的路径中将所有含name的命令都列出来,包括alias
作用:
通过type我们可以知道每个命令是不是bash的内置命令。type可以做类似于which命令的用途吧。
(三)、shell的变量功能
变量就是一组文字或符号等,用来替换一些设置或者是一串保留的数据;
2.3.1. 变量的显示和设置:echo,unset
变量的显示: echo
变量在被显示时,前面必须加上“$”符号
例如:
ehco $PATH
echo ${PATH}
格式:
echo $变量 或者 echo ${变量}
设置一个变量直接用等号就行了
例如我们执行:
mytest=test
我们设置了一个mytest变量,它的内容是test 我们可以拿echo $mytest
查看一下内容。变量的设置规则
变量和变量内容以一个等号连接
等号两边不能直接接空格符
变量名称只能是英文字母和数字,且只能是字母开头
如果变量内容含有空格,可使用双引号“ ”或者单引号’ ’将变量内容结合起来,有特殊字符也是一样的用引号将变量内容结合起来
- 双引号内的特殊字符,能保持原有的特性
- 单引号内的特殊字符则只能是一般字符(纯文本)
例如:
test=“hello $” 和test=‘hello $’
前者的结果是hello 后者的结果是hello $;可用转义符“\”将特殊字符转换成一般字符;
一串命令中如果还有其他命令提供信息,可以使用反单引号` 后者$(命令)。
如果需要在变量后面追加内容,则可以使用
"${变量名称}"累加内容 或者"$变量"累加内容
eg:test= "$test"hello
如果变量需要在其他子程序中执行,需要一export来使该变量转换成环境变量
通常大写字母为系统默认变量,自行设置变量请用小写字母,方便判断(当然这个随意)
取消变量的方法为使用unset变量名称。
2.3.2. 变量键盘读取、数组的声明:read, array,declare
变量键盘读取
格式:
read -pt 变量
参数解释:
- -p: 后面可接提示符
- -t: 后面可接等待的秒数,表示系统不会一直等待用户的输入
eg:
read test
表示需要用户输入test的值;-p “Please input name” -t 30 name 表示提示你在30秒内输入namedeclare / typeset
这个是用来声明变量类型的,如果后面不接任何参数的话,那么bash就会将所有的变量名称和内容全部调用出来。
格式:
declare [-aixr] 变量
参数:
- -a : 将后面的变量定义成数组(array)类型
- -i : 将后面的变量定义成整型(Integer)类型
- -x : 用法he export一样,将后面的变量设置为环境变量
- -r :将变量设置为readonly类型,即该变量不能被更改内容,也不能重设
eg:
sum=300+100
sum结果为300+100declare -i sum=300+100
sum结果为400注:
1. 变量不声明类型的话,默认为字符串。
2. bash中变量最多是整型,没有小数。
3. 如果我们想将环境变量变成自定义变量的话,可使用 declare +x 变量。
数组类型(array)
格式:
数组名[index]=内容
或者
数组名=(值1 值2 ... 值n)
eg:
test[1]="hello"
test[2]="eorld"
echo ${test[1]} ${test[2]}
2.3.3. 与文件系统及程序的限制关系:ulimit
用于限制用户的系统资源的,包括打开的文件数量,可使用cpu时间,可使用内存总量;
格式:ulimit [-SHacdfltu] [配额]
参数:
- -H: hard limit, 严格的设置,表示不能超过设置的这个值。
- -S:soft limit,警告的设置,可以超过这个值,但是超过了会有警告,但是一般这个值比hard的值小。
- -a:后面不接任何参数,可列出所有的限制额度。
- -c:当某些进程发生错误的时候,系统可能会将该进程在内存中的信息写成文件(排错用), 这种文件称为内核文件。这个是为了限制每个内核文件的最大容量。
- -f:此shell可以创建的最大文件容量,一般可设为2GB,单位是KB
- -d:进程可使用的最大断裂内存容量。
- -l:可用于锁定的内存量。
- -t:可使用的最大CPU时间,单位为秒。
- -u:单一用户可以使用的最大进程数量。
注:如果我们想要复原ulimit的设置最简单的方式是注销后登录,不然就直接通过ulimit重新设置,如果是一般用户如果以ulimit设置-f的大小,他只能继续减少文件容量。
2.3.4. 变量内容的删除、替代和替换
- 变量内容的删除和替换
变量设置方式 | 说明 |
---|---|
${变量#关键字} | 若变量内容从头开始的数据符合关键字,则将符合的最短数据删除掉 |
${变量##关键字} | 若变量内容从头开始的数据符合关键字,则将符合的最长数据删除掉 |
${变量%关键字} | 若变量内容从尾向前的数据符合关键字,则将符合的最短数据删除掉 |
${变量%%关键字} | 若变量内容从尾向前的数据符合关键字,则将符合的最短数据删除掉 |
${变量/旧字符串/新字符串} | 若变量内容符合旧字符串,则将第一个旧字符串替换成新字符串 |
${变量//旧字符串/新字符串} | 若变量内容符合旧字符串,则将全部的旧字符串替换成新字符串 |
2. 变量的测试和替换
变量设置方式 | str没有设置 | str为空字符串 | str已设置成了非空字符串 |
---|---|---|---|
var= str | |||
var= str | |||
var=${str+expr} | var= | var=expr | var=expr |
var=${str:+expr} | var= | var= | var=expr |
var= str | |||
var=${str:=expr} | str=expr var=expr | str=expr var=expr | str=不变 var=expr |
var=${str?expr} | expr输出值stderr | var= | var=str |
var=${str:?expr} | expr输出值stderr | expr输出值stderr | var=str |
三、命令别名和历史命令
(一)、命令别名设置:alias,unalias
格式:alias 别名=’命令 参数 ..’
别名的设置和参数的定义规则几乎相同。
unalias是取消别名的。
(二)、历史命令:history
格式:
history [n] —–eg: history 3
n是数字,列出最近n条命令行
history [-c]
-c:将目前shell中的所有历史命令全部清除
history [-raw] histfiles
- -r 将histfiles的内容读到目前shell的history记忆中
- -a 将目前新增的history命令新增如histfiles文件中,若没有加histfiles,则默认写入~/.bash_history文件中
- -w 将目前的history记忆内容全部写到histfiles文件中
!number
number是数字,表示执行第几条命令,这个数字是你用history查询得到的第一列的那个数字
!command
表示由最近的命令向前搜索命令串开头为command的那个命令,并执行
!!
表示执行上一个命令
四、杂项
(一)、路径与命令查找顺序
- 以相对/绝对路径执行命令
- 由alias找到该命令执行
- 由bash内置的(builtin)命令来执行
- 通过$PATH这个变量的顺序找到第一个命令来执行
(二)、通配符
符号 | 意义 |
---|---|
* | 代表0-无穷多个字符 |
? | 代表一定有一个任意字符 |
[] | 代表一定有一个中括号内的字符(非任意字符),例如[abcd]表示一定有一个字符,是a,b,c,d中任意一个 |
[-] | 若有减号在中括号中,代表在编码顺序内的所有字符。例如[0-9]代表0-9之间的所有数字 |
[^] | 若中括号的第一个字符为指数符号,那表示原向选择,例如[^abc] 代表一定有一个字符,只要是非a,b,c之外的其他字符就接受。 |
(三)、特殊字符
符号 | 内容 |
---|---|
# | 批注,这个最常被使用在script当中,视为说明。其后的数据不执行 |
\ | 转义字符,将“特殊字符或通配符”还原成一般字符 |
| | 管道(pipe),分隔两个管道命令的界定 |
; | 连续命令执行分隔符,连续性命令的界定 |
~ | 用户的主文件夹 |
$ | 使用变量前导符,即是变量之前需要加的变量替代值 |
& | 作业控制,将命令变成背景下工作 |
! | 逻辑运算意义上的“非”的意思 |
/ | 目录符号,路径分隔的符号 |
,>> |
数据流重定向,输出导向,分别是“替换”与“累加” |
<,<< | 数据流重定向,输人导向 |
’ ‘ | 单引号,不具有变量置换的功能 |
” “ | 具有变量置换的功能 |
“ | 两个“ ` ”中间可以先执行的命令,也可以用$() |
() | 在中间为子shell的起始和结束 |
{} | 在中间为命令块的组合 |
五、数据流重定向
作用:数据流重定向就是将某个命令执行后应该出现在屏幕上的传输到其他的地方。
(一)、数据流重定向的定义
(1)、命令执行过程数据的传输情况
解释下:当我们执行一个命令的时候,我们可能需要从文件中读取数据,经过处理后输出到屏幕上。
Standard Output(标准输出)
标准输出就是命令执行后得到的正确的信息。
代码为1,使用>或者>>。
Standard Error Output(标准错误输出)
命令执行失败后得到的错误信息。
代码为2,使用2>或者2>>。
Standard Input(标准输入)
代码为0,使用< 或者<<。
注:使用 > 的时候,如果需要输出到的文件不存在就直接创建,然后将信息写入文件,如果存在,就直接覆盖存入。如果想要追加存储的话,就使用 >> 。 标准输出其实是 1> / 1>> ,但是默认是1,所以1可以省略,记住 不要在数字和 > 符号间加空格。
eg: 假设我们执行 ll 命令展示当前目录下的信息,这个命令直接是直接打印在屏幕上的,而如果我们需要将其保存起来,就可以使用 ll > 1.txt
就是将得到的信息存到1.txt文件中,这个时候我们使用cat 2.txt
就可以读取到当时我们ll得出来的结果了。记住 > 是覆盖, >> 是追加。如果我们需要报错误信息保存起来,只需要在命令后加上标准错误输出就好了。
注:如果我们想同时将正确和错误数据存到同一个文件中的话,我们可以使用 2>&1或者 &>
。
(2)以下解释 < 作用:
简单来说就是将原本需要键盘输入的数据改由文件内容来代替。
六、sed工具
sed本身是个管道工具,除了可以分析标准输入之外,还能将数据进行替换、删除、新增、选取特定行等操作。
命令:sed [-nefr][动作]
参数解释:
-n
使用安静模式,在一般的sed用法中,所有来自STDIN(标准输入)的数据一般都会被列出到屏幕上,但如果加上-n参数,则只有经过sed特殊处理的那一行(或者操作)才会被列出来。
-e
直接在命令行模式上进行sed的动作编辑。
-f
直接将sed的动作写在一个文件内,-f filename 则可以执行filename内的sed操作。
-r
sed的动作支持的是扩展型正则表达式的语法(默认是基础正则表达式)。
-i
直接修改读取的文件内容,而不是由屏幕输出。
动作说明 :
[n1][,n2] function
- n1,n2 不一定存在,一般代表选择进行动作的行数,例如:我们的动作在10-20行之间进行的话,表示为
10,20 [动作行为]
- function的参数:
- a:新增,a后面可接字符串,这些字符串会在目前的下一行出现。
- c:替换,c后面可接字符串,这个字符串可以替换 n1, n2 之间的行。
- d:删除,d后面通常不接参数。
- i :插入,i 后面可接字符串,这些字符串会在目前的上一行出现。
- p:打印,将某个选择的数据打印出来,通常p会与参数sed -n 一起。
- s:替换,直接进行的替换。
- n1,n2 不一定存在,一般代表选择进行动作的行数,例如:我们的动作在10-20行之间进行的话,表示为
注:利用sed直接修改文件内容
命令:sed -i ……
七、文件格式化和其相关处理
(一)、格式化打印
把结果按照我们需要的格式打印出来。
格式:printf '打印格式' 实际内容
参数:
- \a 警告声音输出
- \b 退格键
- \f 清除屏幕
- \n 换行
- \r 即enter键
- \t 水平的tab键
- \v 垂直的tab键
- \xNN NN为两位数的数字,可以转换数字为字符
(二)、awk: 数据处理工具
awk 是将一行分成数个“字段”来处理。
格式: awk '条件类型 1{动作 1} 条件类型2{动作2}..........filename'
eg: last -n 5 | awk '{printf $1 "\t" $3 "\n"}'
1. awk处理过程:
- 读入第一行,并将第一行的数据填入$0, $1, $3等变量中
- 依据条件类型的限制,跑哪盾啊是否需要进行后面的动作
- 做完所有的动作和条件类型
- 重复上面的操作,直到数据读完。
2. awk内置变量
变量名称 | 代表意义 |
---|---|
NF | 每一行($0)拥有的字段总数 |
NR | 目前awk所处理的是第几行的数据 |
FS | 目前的分隔字符,默认为空格键 |
3. awk的逻辑运算符
> < >= <= == !=
(三)、文件比较工具
1. diff
diff用于比较两个文件之间的区别的,以行为单位。
格式:
diff [-bBi] from-file to-file
参数:
from-file :一个文件名,作为欲比较文件的文件名;
to-file :一个文件名, 作为目的比较文件的文件名;
-b: 忽略一行当做仅有多个空白的区别;
-B:忽略空白行的区别;
-i:忽略大小写的区别。
2. cmp
以字节为单位比较。
格式:
cmp [-s] file1 file2
参数:
-s :将所有的不同点的字节处都列出来,因为cmp默认仅输出第一个不同点。
3. patch
4. pr
注:
1. 介绍一个利用cat 创建文件的方法
命令:cat > 文件名
然后输入内容 ctrl + d 离开