认识Shell
Shell原意为贝壳
Linux系统中的shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
可以使用命令查看当前使用的是哪种shell以及当前Linux系统中都支持哪些shell种类。
查看当前系统使用的shell
查看当前Linux系统所支持的shell种类
其中/bin/bash是目前大多数Linux版本采用的默认shell。Bash的全称为Bourne Again Shell,是最受欢迎的开源软件项目之一。
常见的shell解释器程序有很多种,使用不同的shell时,其内部指令、命令行提示等方面会存在一些区别。
Shell脚本
只要将平时使用的各种Linux命令按顺序保存到一个文本文件,然后添加可执行权限,这个文件就成为一个shell脚本了。
编写一个恰到好处的shell脚本程序,可以批量处理、自动化地完成一系列维护任务、大大减轻管理员的负担。
周期性的任务可以通过Crond服务来管理,而步骤复杂、操作繁琐的任务可以使用Shell脚本来批量处理,两相结合就可以非常灵活、自主地完成各种系统运维工作。Shell脚本负责具体的备份操作,Crond服务负责控制备份周期。
1、脚本的编写
Shell脚本主要由开头部分、注释部分以及语句部分组成
1)开头
“#!/bin/bash”是一行特殊的脚本声明,表示此行以后的语句通过/bin/bash程序来解释执行。
符号“#!”用来告诉系统它后面的参数是用来执行该文件的程序。
2)注释
其它以”#”开头的语句表示注释信息,建议在程序中使用注释,即使过了长时间也能很快的了解脚本的用途。
3)语句
Linux各种命令的集合
2、脚本的执行
编写完成shell脚本后,需要赋予执行权限
执行此脚本文件后,输出结果与依次执行这两条命令是相同的,从而实现了“批量处理“的自动化过程。
Linux还提供了执行shell脚本的方式——指定某个shell来解释脚本语句,或者通过内部命令source(或点号”.”)来加载文件的源代码执行。
例如,使用”sh first.sh”或“. first.sh”都可以执行firsh.sh脚本中的语句。
注意:以上三种执行方式不添加执行权限也可以执行文件
3、脚本调试
bash -n /path/to/scriptfile 检测脚本中的语法错误
bash -x /path/to/scriptfile 调试执行
Shell变量
Shell变量用来存放系统和用户需要使用的特定参数(值)。而且这些参数可以根据用户的设定或系统环境的变化而相应变化。
常见的Shell变量的类型包括自定义变量、环境变量、预定义变量、位置变量。
1、自定义变量
自定义变量是由系统用户自己定义的变量,只在用户自己的Shell环境中有效,因此又称为本地变量。
1)定义新的变量
定义变量的基本格式为”变量名=变量值“,等号两边没有空格。
[root@localhost ~]# name=tom
[root@localhost ~]# age=20
变量名称命名规则:
a.不能使程序中的保留字:例如if, for
b.只能使用数字、字母及下划线,且不能以数字开头
c.见名知义
d.统一命名规则:驼峰命名法
2)查看和引用变量的值
2、环境变量
环境变量指的是出于运行需要而由Linux系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录、命令替换路径、用户当前目录、登录终端等。环境变量的值由linux系统自动维护,会随着用户状态的改变而改变。
使用env命令可以查看当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途。
例如USER表示用户标识、HOME表示用户的宿主目录、LANG表示语言和字符集、PWD表示当前所在的工作目录、PATH表示命令搜索路径….
查看当前Linux系统中所有的环境变量
可以用命令修改环境变量的搜索路径,这样写完shell脚本以后可以直接输入脚本名称直接执行,不用每次输入文件的路径。
临时修改:只对当前终端有效
永久修改:永久有效
修改家目录下的隐藏文件.bash_profile,添加指定的搜索路径即可,搜索路径之间用“:”分隔,添加完成后需要重新读取该配置文件让其生效。
重新读取配置文件使其立即生效
将搜索路径添加完成后直接输入文件名即可运行成功
PATH的搜索顺序:从左到右依次搜索,
同样在/usr/bin下面写一个同名的脚本文件,执行时依然执行/testdir/script目录下的文件,当把hash缓存清空后,即执行了/usr/bin目录下的first.sh文件,如果把缓存再次清空,执行脚本文件报错,清空缓存后,有可以执行了。
从此可见,缓存(hash)中的命令优先于搜索路径,如果缓存中有这条命令,就不去搜索PATH变量,文件不存在也执行hash,会报错;清空缓存后,按照PATH变量的搜索顺序依次查找,当PATH变量有多个可以匹配,执行先匹配到,匹配到第一个脚本时不再往下搜索。
环境变量的配置文件
全局配置文件:/etc/.bash_profile
个人配置文件:~/.bash_profile
3、预定义变量
预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用$符号和另一个符号组合表示,较常用的几个预定义变量如下:
$#:表示命令行中位置参数的个数。
$*:传递给脚本的所有参数,全部参数合为一个字符串。
$@: 传递给脚本的所有参数,每个参数为独立字符串
$@ $* 只在被双引号包起来的时候才会有差异
$?:表示前一条命令执行后的返回状态,0表示成功,非0表示失败。
$0:表示当前执行的脚本或程序的名称。
示例:备份目录数据,并显示备份信息
4、位置变量
位置变量:位置变量也称为位置参数,在脚本代码中调用通过命令行传递给脚本的参数
当执行命令行操作时,第一个字符表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。
$1, $2, …:对应第1、第2等参数, shift [n]换位置
示例:计算两个数值的和
示例:判断给出的文件的行数
定义只读变量
只读变量:只能声明,但不能修改和删除
readonly name
declare -r name
示例:定义只读变量
注意:只读变量同样只在当前终端中有效
变量赋值的特殊操作
1)双引号(”)
双引号主要起了一个界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来,否则会报错;其他情况下双引号通常可以省略。
在双引号范围内,使用“$”符号可以引用其他变量的值(变量引用),从而能够直接调用现有变量的值来赋值给新的变量。
2)单引号(’)
当要赋值的内容中包含$、”、 \等具有特殊含义的字符时,应使用单引号括起来。在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。但赋值内容中包含单引号时,需使用“\’”符号进行转义,以免冲突。
3)反撇号(`)
反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围内必须是能够执行的命令行,否则将会出错。
需要注意的是,使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用“$()”来代替反撇号操作,以解决嵌套的问题。
变量的作用范围
1、设置局部变量
默认情况下,新定义的变量只在当前的Shell环境中有效,因此成为局部变量。当进入子程序或新的子Shell环境时,局部变量将无法再使用。
2、设置全局变量
为了使用户定义的变量在所有的子Shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为”全局变量“可以同时制定多个变量名称作为参数(不需使用$符合),变量名之间以空格分隔。
使用export导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了,也可以将之前的局部变量设置使用export命令设置为全局变量,使其在子shell中可以调用。
注意:设置全局变量后,子进程可以调用父进程的变量,反之则不可以。
条件测试
使用专门的测试工具test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值0表示条件成立)。
test 条件表达式
或
[ 条件表达式 ]
两种方式作用完全相同,但后者更为常用,也更贴近编程习惯。需要注意的是,方括号与表达式之间需要至少一个空格进行分割。
根据需要测试的条件类别不同,条件表达式也不一样。比较常用的条件操作包括文件测试、整数值比较、字符串比较,以及针对多个条件的逻辑测试。
执行条件测试操作后,通过预定义变量”$?“可以获得测试命令的返回状态值,从而判断该条件是否成立。echo $?查看返回状态值。
1、文件测试
存在性测试
-e FILE: 文件存在性测试,存在为真,否则为假
-a FILE:同-e
存在性及类别测试
-b FILE: 是否存在且为块设备文件
-c FILE: 是否存在且为字符设备文件
-d FILE: 是否存在且为目录文件
-f FILE: 是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE: 是否存在且为命名管道文件
-S FILE: 是否存在且为套接字文件
文件权限测试
-r: 测试当前用户是否有权限读取(Read)
-w: 测试当前用户是否有权限写入(Write)
-x: 测试是否这只有可执行权限(Excute)
文件特殊权限测试
-g FILE:是否存在且拥有sgid权限
-u FILE:是否存在且拥有suid权限
-k FILE:是否存在且拥有sticky权限
文件大小测试
-s FILE: 是否存在且非空;
文件是否打开
-t fd: fd表示文件描述符是否已经打开且与某终端相关
-N FILE:文件自动上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
双目测试
FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode
FILE1 -nt FILE2: FILE1是否新于FILE2
FILE1 -ot FILE2: FILE1是否旧于FILE2
2、数值比较
-eq: 第1个数等于(Equal)第2个数
-ne: 第1个数不等于(Not Equal)第2个数
-gt: 第1个数大于(Greater Than)第2个数
-lt: 第1个数小于(Lesser Than)第2个数
-le: 第1个数小于或等于(Lesser or Equal)第2个数
-ge: 第1个数大于或等于(Lesser or Equal)第2个数
3、字符串比较
=: 第1个字符串与第2个字符串相同
!=: 第1个字符串与第2个字符串相同,其中!符号表示取反的意思
-z: 检查字符串是否为空(Zero),对于未定义或赋予空值的变量将视为空串。
==: 是否等于;
>: ascii码是否大于ascii码
<: 是否小于
!=: 是否不等于
=~: 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;
-z "STRING":字符串是否为空,空为真,不空为假
-n "STRING":字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
算术运算
bash中的算术运算
+, -, *, /, %取模(取余) , **(乘方)
实现算术运算:
let var=算术表达式
var=$[算术表达式]
var=$((算术表达式))
var=$(expr arg1 arg2 arg3 …)
declare –i var = 数值
echo ‘算术表达式’ | bc
乘法符号有些场景中需要转义, 如*
bash有内建的随机数生成器: $RANDOM( 1-32767)
echo $[$RANDOM%50] : 0-49之间随机数
赋值
增强型赋值:
+=, -=, *=, /=, %=
let varOPERvalue
例如:let count+=3 自加3后自赋值
自增,自减:
let var+=1
let var++
let var-=1
let var–
示例:算术运算
示例:j自增自减运算
逻辑测试
&&:逻辑与,表示“而且”的意思,只有当前后两个条件都成立时,真个测试命令的返回值才为0。使用test命令测试时,&&可改为-a。
||:逻辑与,表示“或者”的意思,只有前后两个条件有一个成立时,整个测试命令的返回值为0。使用test名测试时,||可改为-o。
!:逻辑否,表示“不”的意思,只有当指定的条件不成立时,正测试命令的返回值才为0。
逻辑运算
true, false
1, 0
与:&&
1 与 1 = 1
1 与 0 = 0
0 与 1 = 0
0 与 0 = 0
或:||
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非: !
! 1 = 0
! 0 = 1
短路运算
短路与:
第一个为0,结果必定为0;
第一个为1,第二个必须要参与运算;
短路或:
第一个为1,结果必定为1;
第一个为0,第二个必须要参与运算;
异或: ^
异或的两个值,相同为假,不同为真
聚集命令
有两种聚集命令的方法
复合式: date; who | wc –l 命令会一个接一个地运行
子shell: (date; who | wc -l ) >> /tmp/trace
所有的输出都被发送给单个STDOUT和STDERR
组合测试条件
第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如: [ -e FILE ] && [ -r FILE ]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行;
# [ -z “$HOSTNAME” -o $HOSTNAME "==\"localhost.localdomain" ] && hostname www.magedu.com
# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
示例:判断两个变量的大小
退出状态
进程使用退出状态来报告成功或失败,$? 变量保存最近的命令退出状态
0 代表成功
1-255 代表失败
示例:ping一个ip地址,并查看其返回值
退出状态码
bash自定义退出状态码
exit [n]:自定义退出状态码;
注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
示例:根据测试条件返回状态码
read命令:接受用户输入
使用read来把输入值分配给一个或多个shell变量:
read [选项] [参数]
-p 指定要显示的提示信息
-t 指定读取值时等待的时间(秒)
-n 读取用户输入的前几个字符
-s 隐藏用户的输入字符
-r 允许输入包含反斜杠
-d 以-d选项指定的字符作为结束符,如空格、特殊符号
read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量。
read -p “Enter a filename: “ FILE
示例:编写修改当前用户的密码脚本
使用-s选项可隐藏用户要输入的字符信息,如密码等信息
原创文章,作者:cyh5217,如若转载,请注明出处:http://www.178linux.com/33473
评论列表(1条)
学习态度端正,博客不仅写的完善而且有自己的想法,通过自己的思路汇总,足以见其对知识的理解深刻,望后期能持续学习,提升自我。