- A+
shell前言
什么是shell
shell-‘壳’ 命令解释器,一种应用程序
shell语言特点
SHELL语言是指UNIX操作系统的命令语言,同时又是该命令语言的解释程序的简称。
Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。
Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令,作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支,它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。
shell能做什么
Shell 能做什么?
1. 自动化批量系统初始化程序 (update,软件安装,时区设置,安全策略...)
2. 自动化批量软件部署程序 (LAMP,LNMP,Tomcat,LVS,Nginx)
3. 应用管理程序 (KVM,集群管理扩容,MySQL,DELLR720批量RAID)
4. 日志分析处理程序(PV, UV, 200代码, !200代码, top 100, grep/awk)
5. 自动化备份恢复程序(MySQL完全备份/增量 + Crond)
6. 自动化管理程序(批量远程修改密码,软件升级,配置更新)
7. 自动化信息采集及监控程序(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
8. 配合Zabbix信息采集(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
9. 自动化扩容(增加云主机——>业务上线)
zabbix监控CPU 80%+|-50% Python API AWS/EC2(增加/删除云主机) + Shell Script(业务上线)
10. 俄罗斯方块,打印三角形,打印圣诞树,打印五角星,运行小火车,坦克大战,排序算法实现
shell的执行方式
1 执行1:bash file1 2 执行2:sh file1 3 执行3:. file1 4 执行4: source file1
多种执行方式的区别:
1.准备环境
1 vim bash.sh 2 #!/usr/bin/bash 3 cd /home/ 4 ls
2. 一种执行方式测试
. bash.sh
3.观察目录改变了。说明影响的是当前。并使用子shell执行方式执行。
该种执行方式,是不同于前者SUB shell执行。
而是在当前shell执行,用于影响当前shell环境。
shell解释器在哪
1 cat /etc/shells 2 或 3 chsh -l
变量
shell 变量? 用一个固定的字符串去表示不固定的内容,便于修改。
自定义变量
用户自定义变量是最常用的变量类型,其特点是变量名和变量值都是由用户自由定义的。
学习要点
定义变量: 变量名=变量值
引用变量: $变量名或 ${变量名}
查看变量: echo $变量名; "set"可以查看所有变量(包括自定义变量和环境变量)
取消变量: unset 变量名
定义变量
该如何定义变量呢?很简单,只需执行"变量名=变量值"命令即可,不过要遵守变量定义规则。例如
1 [root@localhost ~]# name="test 666"
变量调用
当我们需要提取变量中的内容时,需要在变量名之前加入"$"符号。
那么最简单的变量调用就是通过 echo 命令输出变量的值。命令如下
1 #定义变量name 2 3 [root@localhost ~]# name="test 666" 4 5 #输出变量name的值 6 7 [root@localhost ~]# echo $name 8 9 test 666
错误定义示范
变量的定义就是这么简单,但是如果不遵守变量定义规则,就会报错。比如:
#变量名不能以数字开头 [root@localhost ~]# 2name="test 666" -bash: 2name=test 666: command not found #等号左右两侧不能有空格 #变量的值如果有空格,必须用引号包含 [root@localhost ~]# name=test 666 -bash: 666: command not found
重复定义变量
重复定义变量会进行变量叠加。例如:
#定义变量aa的值是123
#重复定义变量aa的值是源aa的值加上456
1 [root@localhost ~]# aa="$aa"456 2 3 #调用变量aa,发现值已经变成了123456 4 5 #在进行变量叠加时,也可以使用${变量名}格式 6 7 [root@localhost ~]# aa=${aa}789 8 9 [root@localhost ~]# echo $aa 10 11 123456789
这里要小心,在进行变量叠加时,变量名需要用双引号或 ${} 包含。
变量查看
我们可以通过 echo 命令查询已经设定的变量的值,这种查询是已知变量名查询变量值。
但是如果我不知道变量名,那么可以查询系统中已经存在的变量吗?
[root@localhost ~]# set
变量删除
1 [root@localhost ~]# aa="$aa"456 2 3 #调用变量aa,发现值已经变成了123456 4 5 #在进行变量叠加时,也可以使用${变量名}格式 6 7 [root@localhost ~]# aa=${aa}789 8 9 [root@localhost ~]# echo $aa 10 11 123456789
示例
使用变量前
需求:编写测试主机在线的脚本。当主机在线提示在线,当主机不在线提示不在线。
编写脚本
ping -c1 192.168.100.10 &> /dev/null && echo 192.168.100.10up || echo 192.168.100.10down
注释:&&和||是三目表达式、&& 前面的命令成功。执行后面的命令、||前面的命令失败。执行后面的命令
思考:如果更换测试IP。需要修改脚本的哪些部分?
需要修改三个部分
使用变量后
编写脚本
1 #!/bin/bash 2 3 ip=192.168.100.10 4 5 ping -c1 $ip &>/dev/null && echo $ip up || echo "$ip down"
思考:添加变量后,修改一处即可。
交互定义变量
read 从键盘读入变量值
赋值方式:read 变量名
示例
1 read -p "请输入您测试的IP地址:" ip 2 3 ping -c1 $ip &>/dev/null && echo " $ip up" || echo "$ip 4 down"
注意事项:3种引号
定义或引用变量时注意事项:
" " 弱引用
' ' 强引用
` ` 优先执行
1 双引号1 2 [root@localhost ~]# schoo=1000 phone 3 错误示范,shell把空格识别做命令分隔符。 4 bash: phone: 未找到命令 5 [root@localhost ~]# schoo="1000 phone" 6 正确示范,变量值中的空格,被转义为一个普通符号 7 [root@localhost ~]# echo $schoo 8 1000 phone 9 执行成功。 10 11 双引号2 12 [root@localhost ~]# schoo=$schoo is good 13 错误示范,已有变量的基础上,再追加内容。 14 bash: is: 未找到命令 15 没有加引号,被识别为两条命令 16 [root@localhost ~]# schoo="$schoo is good" 17 正确示范,加了双引号。组成了整体,空格失去含义。 18 [root@localhost ~]# echo $schoo 19 1000 phone is good 20 成功
1 单引号 2 [root@localhost ~]# schoo='$schoo 666' 3 单引号,转义一切符号 4 [root@localhost ~]# echo $schoo 5 $schoo 666 6 $也被转义了。一切都被转义了。
1 反引号 2 [root@localhost ~]# schoo=`date` 3 反引号是优先执行。先执行date的命令,再执行定义变量。 4 [root@localhost ~]# echo $schoo 5 2022年 08月 23日 星期二 14:57:13 CST 6 所以看到变量的结果,是时间
注意
1.变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则: 2.命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。 3.中间不能有空格,可以使用下划线(_)。 4.不能使用标点符号。 5.不能使用bash里的关键字(可用help命令查看保留关键字)。 6.起变量名,请使用五个字母以上。
整数运算
1 方法一:expr 2 语法 3 expr 1 + 2 4 expr $num1 + $num2 5 +加 6 -减 7 *乘(*是任意字符,使用 转义一下。) 8 /除 9 %取余 10 需求: 11 运算学员的成绩总分 12 制作脚本 13 [root@localhost ~]# vim sum.sh 14 #!/bin/bash 15 read -p "请输入您的第一门成绩: " number1 16 read -p "请输入您的第二门成绩: " number2 17 echo -n "总成绩是: " 18 expr $number1 + $number2 19 授权脚本 20 [root@localhost ~]# chmod +x sum.sh 21 测试脚本 22 [root@master1 ~]# ./sum.sh 23 请输入您的第一门成绩: 60 24 请输入您的第二门成绩: 70 25 总成绩是: 130
小数运算(了解)
1 请提前安装计算器程序bc 2 echo "2*4" |bc 3 echo "2^4" |bc 4 echo "scale=2;6/4" |bc 5 bc:交互运算器 6 scale=2 保留小数点后面两位
环境变量(了解)
前言
自定义变量,只能再当前shell生效。其他shell是不生效的,说白了,你的变量只能你用。那如果有些变量,需要所有的用户都使用,怎么办呢?
1 定义环境变量: 2 直接声明 3 方法一 export back_dir2=/home/backup 4 声明环境变量 5 转换声明 6 方法二 export back_dir1 将自定义变量转换成环境变量 7 转换环境变量
变量作用范围: 在当前shell和子shell有效
想使变量。在当前用户登陆后一直生效,可以将变量放到~/.bash_profile
想使变量。在所有用户登陆后一直生效,可以将变量放到/etc/profile
1 示例 2 [root@localhost ~]# abc=123 3 定义普通变量1 4 [root@localhost ~]# def=456 5 定义普通变量2 6 [root@localhost ~]# bash 7 打开子shell 8 [root@localhost ~]# echo $abc 9 调用普通变量,失败 10 [root@localhost ~]# echo $def 11 调用普通变量,失败 12 [root@localhost ~]# exit 13 退出子shell 14 exit 15 [root@localhost ~]# export abc 16 讲变量声明为环境变量。儿子shell都能用。 17 [root@localhost ~]# bash 18 打开子shell 19 [root@localhost ~]# echo $abc 20 发现变量可以用了。 21 123 22 [root@localhost ~]# echo $def 23 普通变量还是不行。
位置变量和预定义变量(了解)
位置变量语法
1 位置变量 2 命令 参数1 参数2 参数3 ....9以后特殊定义 3 $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 ...
1 示例 2 需求 3 制定脚本程序,用户自行输入两门学科的成绩(整数),自动算出平均分。 4 制作脚本 5 [root@localhost ~]# vim avg.sh 6 #!/bin/bash 7 echo "($1+$2)/2" | bc 8 [root@localhost ~]# chmod +x avg.sh 9 测试脚本 10 [root@localhost ~]# ./avg.sh 88 77 11 82 12 请思考 13 位置变量和read读取变量,到底用哪个? 14 使用谁都可以。 15 #!/bin/bash 16 read -p "请输入您的第1门成绩: " num1 17 read -p "请输入您的第2门成绩: " num2 18 echo -n "您的平均成绩是:" 19 echo "($num1+$num2)/2" |bc
总结 1.位置变量就是$1,$2,$3,$4 2.位置变量预先已经被定义过了。 3.用户使用时,必须携带参数。 4.位置变量不是程序设计的唯一方法。比如read也可以。
总结
这两类变量,在设计系统时就已经定义好了。
需要使用时,直接调用即可。
练习
编写自动创建用户并设置初始化脚本
1 vim create.sh 2 #!/bin/bash 3 read -p "请输入要创建用户的名称:" name 4 useradd ${name} 5 echo "123456" | passwd --stdin ${name} &> /dev/null 6 echo ${name} 已经创建完成,密码是123456 7 [root@bogon ~]# sh create.sh 8 请输入要创建用户的名称:kk 9 kk 已经创建完成,密码是123456