shell脚本

 

一:shell脚本的概念

1:自动化系统初始化(update,软件安装,时区设置,安全策略)

2:自动化批量软件部署程序(lnmp,llamp,nginx)

3:管理应用程序(kvm,集群管理扩容,mysql)

4:日志的分析处理程序

二:shell脚本的变量

1:变量的命名规则

1)命名只能使用英文字母,数字和下划线,首个字符不能以数字开头

2)等号的左右2边,不能有空格,可以使用下划线,变量的值如果有空格的话,可以使用双引号包括,里面的$号,转义可以使用

但是单引号的话,里面内容全是普通字符

3)环境变量建议大写,比较好区分

4)如果需要增加变量的值,可以进行变量值的增加,

  第一种:"$name 变量名"

  第二种:${name}dasdasd

关于双引号和单引号的问题:

双引号能够识别变量

单引号不能识别变量,原样输出

2:shell中的特殊符号

符号 作用
' ' 单引号,里面的所有特殊符号都没有用,都是普通字符
" " 双引号,$,``,\ 拥有调用变量的值,引用命令
`` 反引号,括起来的内容就是系统命令
$() 和反引号作用一样,引用系统命令
() 用于一串命令的执行,()中的命令会在子shell中执行(当前的shell)
{} 用于一串命令的执行,
[ ] 条件表达式,都放在这里面,-a,-o !逻辑运算,也支持字符串运算
[ [ ] ] 包括了[ ],但是它支持正则表达式,|| && 都支持
# 表示注释
$ 用于调用变量的值 $name
\ 转义字符,跟在他的后面会失去原有的含义
   
   
   

3:双引号和单引号

[root@localhost ~]$ name=sc
#定义变量name 的值是sc
[root@localhost ~]$ echo '$name'
$name
#如果输出时使用单引号,则$name原封不动的输出
[root@localhost ~]$ echo "$name"
sc
#如果输出时使用双引号,则会输出变量name的值 sc

[root@localhost ~]$ echo `date`
2018年10月21日星期一18:16:33 CST
#反引号括起来的命令会正常执行
[root@localhost ~]$ echo '`date`'
`date`
#但是如果反引号命令被单引号括起来,那么这个命令不会执行,―date`会被当成普通字符输出
[root@localhost ~]$ echo "`date'"
2018年10月21日星期一18:14:21 CST
#如果是双引号括起来,那么这个命令又会正常执行

4:反引号

引用系统的命令,相当于$()

[root@localhost ~]$ echo ls
ls
#如果命令不用反引号包含,命令不会执行,而是直接输出
[root@localhost ~]$ echo `ls`
anaconda-ks.cfginstall.loginstall.log.syslog sh test testfile
#只有用反引号包括命令,这个命令才会执行
[root@localhost ~]$ echo $(date)
2018年10月21日星期一18:25:09 CST
#使用$(命令)的方式也是可以的

三:变量的分类

1:用户自定义变量

最常见的变量,有用户自由定义,在当前的shell中执行

1)变量的定义

[root@localhost ~]$ 2name="shen chao"
-bash: 2name=shen chao: command not found
#变量名不能用数字开头
[root@localhost ~]$ name = "shenchao"
-bash: name: command not found
#等号左右两侧不能有空格
[root@localhost ~]$ name=shen chao
-bash: chao: command not found
#变量的值如果有空格,必须用引号包含

2)变量的调用

[root@localhost ~]$ name="shen chao"
#定义变量name
[root@localhost ~]$ echo $name #调用变量使用  $变量名
shen chao
#输出变量name的值

3)变量的查看

[root@localhost ~]$ set [选项]
选项:
-u:如果设定此选项,调用未声明变量时会报错(默认无任何提示)
-x:如果设定此选项,在命令执行之前,会把命令先输出一次
+<参数> :取消某个set曾启动的参数。

[root@localhost ~]$ set
BASH=/bin/bash
…省略部分输出…
name='shen chao'
#直接使用set 命令,会查询系统中所有的变量,包含用户自定义变量和环境变量
[root@localhost ~]$ set -u
[root@localhost ~]$ echo $file
-bash: file: unbound variable
#当设置了-u选项后,如果调用没有设定的变量会有报错。默认是没有任何输出的。
[root@localhost ~]$ set -x
[root@localhost ~]$ ls
+ls --color=auto
anaconda-ks.cfginstall.loginstall.log.syslog sh tdir testtestfile
#如果设定了-x选项,会在每个命令执行之前,先把命令输出一次

[root@localhost ~]$ set +x
#取消启动的x参数  

4)变量的删除

[root@localhost ~]$ unset 变量名  

2:环境变量

系统保存的变量,尽量不要修改,父shell,子shell都能执行

1)环境变量的设置

[root@localhost ~]$  export age="18"
#使用export声明的变量即是环境变量

2)环境变量的查询和删除

env命令可以查看所有的环境变量,set可以查看所有变量  

[root@localhost ~]$ unset gender   #删除环境变量gender
[root@localhost ~]$ env | grep gender

3:位置参数变量

主要就是橡向脚本中传递参数,变量名不能随意改变,变量的作用是固定的

$n n为数字,$1到$9,10以上的参数用{10}
$* 这个变量代表命令中的所有参数,$把所有参数看成一个整体
$@ 也代表所有参数,只不过是每个参数区分对待
$# 命令中所有参数的个数
   

1)$1

[root@localhost sh]$ vim test.sh
#!/bin/sh
echo "shell脚本本身的名字: $0"
echo "传给shell的第一个参数: $1"
echo "传给shell的第二个参数: $2"

 执行的时候  bash test.sh 1 2

2)$* $@

[root@localhost sh]$ vi parameter2.sh
#!/bin/bash
for i in"$*"
#定义for循环,in后面有几个值,for会循环多少次,注意“$*”要用双引号括起来
#每次循环会把in后面的值赋予变量i
#Shell把$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
	do
		echo "The parameters is: $i"
		#打印变量$i的值
	done
x=1
#定义变量x的值为1
for y in"$@"
#同样in后面的有几个值,for循环几次,每次都把值赋予变量y
#可是Shel1中把“$@”中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
	do
		echo "The parameter$x is: $y"
		#输出变量y的值
		x=$(( $x +1 ))
		#然变量x每次循环都加1,为了输出时看的更清楚
	done

$* 都看成一个整体,$@区别看待  

4:预定义变量

已经定义好了的变量

$? 证明上一次执行命令的正确性,正确返回为0,错误则不为0
$$ 当前进程的pid
$! 后台运行的最后一个进程的pid
   
   

 

1)$?

检查上一个命令是否正确的运行,为0就是正确的运行,不为0就是错误的输出

[root@localhost /]# asda
bash: asda: 未找到命令...
[root@localhost /]# echo $?
127
[root@localhost /]# ls
1    boot  etc        home  lib64  mnt        opt   root  sbin  sys  usr
bin  dev   ftp-share  lib   media  nfs-share  proc  run   srv   tmp  var
[root@localhost /]# echo $?
0
[root@localhost /]# 

2)$$ 和 $!

[root@localhost sh]$ vi variable.sh
#!/bin/bash
echo "The current process is $$"
#输出当前进程的PID.
#这个PID就是variable.sh这个脚本执行时,生成的进程的PID
find /root -name hello.sh &
#使用find命令在root目录下查找hello.sh文件
echo "The last one Daemon process is $!"
#输出这个后台执行命令的进程的PID,也就是输出find命令的PID号

5:read定义变量

#/biin/bash
read -p "请输入你的名字:" name
read -s -p  "请输入你的年龄:" age
echo -e "\n"   #换行,不然的话,输出年龄时候,不会换行
echo  "你的名字是$name, 年龄是$age"
~                                    

 

与while语句搭配的使用

就是while能够以行来读取文件,在done < 文本文件 ,read 变量    这个变量就是每一行读取的文件的存储的地方

 

 

四:shell的运算符

shell语言和其他的编程脚本的语言一样,有算术运算符,逻辑运算符,字符串运算符,文件测试符等

1:算术运算符

1)expr 表达式

#加法
[root@localhost ~]# expr 3 + 4
7
[root@localhost ~]# 

#减法
[root@localhost ~]# expr 7 - 5 
2
[root@localhost ~]# 

#乘法(需要转义)
[root@localhost ~]# expr 6 \* 10
60
[root@localhost ~]# 

#除法
[root@localhost ~]# expr 9 / 3
3
[root@localhost ~]# 

2)$(())运算(最常用的运算符)

里面可以不带上$,当然,特殊情况下,必须要带上

#加法
[root@localhost ~]# num1=10
[root@localhost ~]# num2=11
[root@localhost ~]# echo $((num1+num2))
21
[root@localhost ~]# 

#减法
[root@localhost ~]# echo $((num1-num2))
-1
[root@localhost ~]# 

#乘法
[root@localhost ~]# echo $((num1*num2))
110
[root@localhost ~]# 

#除法
[root@localhost ~]# echo $((num1/num2))
0
[root@localhost ~]# l

里面还可以加上括号,改变运算的顺序

3)$[ ]运算(也是最常用的运算符)

#加法
[root@localhost ~]# num1=10
[root@localhost ~]# num2=20
[root@localhost ~]# echo $[num1+num2]
30
[root@localhost ~]# 

#减法
[root@localhost ~]# echo $[num1-num2]
-10
[root@localhost ~]# 

#乘法
[root@localhost ~]# echo $[num1*num2]
200
[root@localhost ~]# 

#除法
[root@localhost ~]# echo $[num2/num1]
2
[root@localhost ~]# 

4)let 运算

用于累加的一个运算,非常好用

i++和++i的区别
1)对变量值的影响
只是对于变量的值而言,没有任何的影响
i和j没有任何影响

2)对于表达式的影响
x=i++ 先赋值在运算,x=i,i++
y=++i 先运算在赋值,
输出的结果为 x=1 ,y=2 ,但是i和j的值都为2
这就是区别

  

 

2:关系运算符

关系运算符,支持数字之间的比较,谁大谁小

运算符 单词 说明 举列
-eq equal 检测2个数是否相等,相等返回true [ $a -eq $b ],返回flase
-ne not equal 检测2数是否相等,不相等返回flase  
-gt great than 检测左边的数是否大于右边的,返回true  
-lt less than 检测左边的数是否小于右边的,返回true  
-ge great than or equal 检测左边的数是否大于等于右边,返回为true  
-le less than or equal 检测左边的数是否小于等于右边的数,返回true  

题目:检查用户是否存在,如果存在就提示用户存在,不存在就提示用户不存在

read -p "请输出要查询的用户名:" username
count=`cat /etc/passwd | grep $username | wc -l`
if [ $count -eq 0 ];then
        echo "$username 不存在"
else
        echo "$username 存在"
fi

#思路就是通过输入的用户,在用户的配置文件中去找寻该用户并统计行数,如果为0就证明没有该用户

3:逻辑运算符

运算符 说明 举列
! 非运算,表达式为true,则返回flase,否则返回true  
-o 或运算,有一个表达式为true,就返回true [ $a -lt 20 -o -gt 100 ],返回true 这个数小于20有大于100,有一个真,返回true
-a 与运算,2个都为true,才返回true  

或运算:有一个为真,就是真

与运算:有一个为假,就是假

4:字符串运算符

[ ] 基本上比较都是放在了 中括号里面的

== 检测2个字符是否相等,返回true  
!= 检测2个字符是否相等,不相等返回true  
-z 检测字符串的长度是否为0,为0返回true  
-n 检测字符串的长度是否为0,不为0返回true  
str 检测字符串是否为空,不为空返回true  
     
     

5:文件测试符

-b file 检测文件是否是块文件,是的话,返回true  
-c file 检测文件是否是字符设备  
-d file 检测文件是否为目录  
-f 检测文件是为文件  
-w 检测文件是否为可写  
-e 检测文件(包括目录)是否存在  
-s 检查文件是否为空  

 6:正则表达式

[ [ ] ] 条件判断语句,支持&&和正则表达式
=~ 正则匹百配,判断左边是否等于右边
^ 以什么开头
^[0-9] 以数字开头
^[0-9]+ 以数字开头,且数字有1到多个
$ 以什么结尾
^[0-9]+$ 以1到多个数字开头切且结尾

 

 

 

 

 

总结性的话语,就是比较数值,判断什么样的条件,可以用 [ ],这个能解决大部分的问题,(())也可用,就是符号是数字类型的

 

 

五:流程控制

一:if语句

格式

if 条件判断;then
    代码
elif 条件判断;then
else
    代码
fi

用于来判断的

二:case语句(if的升级版)

格式:

case 变量 in
条件)
    代码
    ;;
*)
    代码
    ;;
esac

2个语句都能做关于分数的判断的问题

三:for语句

for in循环的语法格式为:for 变量名 in 列表;do 命令;做
列表可以是一个字符串、一个文件名或者一个命令的输出结果
如果列表是一个字符串,那么for循环会将字符串按照空格分割成多个元素,然后依次遍历每个元素
如果列表是一个文件名,那么for循环会读取文件的每一行作为一个元素,然后依次遍历每个元素
如果列表是一个命令的输出结果,那么for循环会将命令的输出结果按照空格分割成多个元素,然后依次遍历每个元素
在for循环中,变量名可以是任意合法的变量名,但建议使用有意义的变量名,以便于代码的可读性和维护性

  

格式:

for i in 变量
do
    代码
done 

这个是原始的,变量可以是文本

还有另外的一个格式:

for ((初值;条件;步长))
do
    代码
done 

利用for来完成指定用户的批量创建

四:while语句

条件必须返回为真才能进行循环,

格式:

while 条件
do
    代码
done
echo 

 

语法格式一:
while [条件]
do
	操作
done

语法格式二:
while read line
do
	操作
done  <  file

通过read命令每次读取一行文件,文件内容有多少行,while循环多少次

  

 

  

 

 

 

  

 

六:shell的总结

1:关于符号的总结

1)[ ]   [ [  ] ] 

[ ]和[ [ ] ] 2个方括号,可以适用于大部分的运算,唯一的不同就是双括号支持正则表达式,和逻辑运算符,&& || 

基本上双括号的功能包括单括号

那就介绍一下 [ ]

支持关系运算符,不能是 > < ,只能是 le lt ge gt eq ne 这些关系运算符,支持逻辑运算符, -a ,-o ! 

字符的运算也支持, -d  -f 等

2) ()(())

支持关系运算符,> < = 逻辑运算符也支持 -a -o !  &&  ||

 

2:语句的总结

for语句和while语句

for语句是以空格来读取文件的,遇见空格就要执行,可以改变分割符 IFS='

'

while语句是以行来读取文件,分割符为空格或者tab

所以在处理文件上面的操作的话,使用while语句比较好

 

 

 

 

 

  

 

  

 

posted @ 2023-10-30 22:06  q_7  阅读(8)  评论(0编辑  收藏  举报