第一章、变量
SHELL前言
什么是shell
Shell是一种计算机操作系统的命令行解释器,它提供了与操作系统内核进行交互的界面。它允许用户通过输入命令来执行各种操作,例如运行程序、管理文件和目录、配置系统设置等。Shell还可以执行脚本,这是一系列预定义的命令和操作的集合,可以自动化和简化复杂的任务。在Unix、Linux和类Unix系统中,常见的Shell包括Bash(Bourne Again SHell)、Csh(C SHell)和Ksh(Korn SHell)。Shell是与操作系统紧密相关的工具,它为用户提供了一种直接而强大的方式来与计算机进行交互。
shell语言的特点
SHELL语言是指UNIX操作系统的命令语言,同时又是该命令语言的解释程序的简称。
Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。
Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;
作为程序设计语言,它定义了各种变量和参数并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。
Shell 能做什么?
- 自动化批量系统初始化程序(update,软件安装,时区设置,安全策略...)
- 自动化批量软件部署程序(LAMP,LNMPTomcat , LVS, Nginx)
- 应用管理程序(KVM,集群管理扩容,MySQL,DELLR720批量RAID)
- 日志分析处理程序(PV,UV,200代码,!200代码, top 100, grep/awk )
- 自动化备份恢复程序(MySQL完全备份/增量 + Crond )
- 自动化管理程序(批量远程修改密码,软件升级,配置更新)
- 自动化信息采集及监控程序(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
- 配合Zabbix信息采集(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache, MYSQL)
- 自动化扩容(增加云主机——>业务上线)zabbix监控CPU 80%+|-50% Python API AWS/EC2(增加/删除云主机)+Shell Script(业务上线)
SHELL执行方式:
shell多种执行方式:
准备测试脚本([root@localhost tmp]# vim file1
echo "hello 2020"
read -p "请输入您的姓名: " name
echo "哈哈$name是大笨蛋")
执行1:bash file1
执行2:sh file1 (which bash which sh 发现是同一个文件。在大多数Unix和Linux系统中,"bash"和"sh"实际上是同一个文件的符号链接(symbolic link)。这意味着"bash"和"sh"都指向同一个可执行文件,通常是Bash解释器。Bash是Bourne Again SHell的缩写,它是一种功能更强大和更灵活的Shell解释器,与传统的Bourne Shell(sh)兼容。因此,当你运行"bash"或"sh"命令时,实际上都在运行Bash解释器。)
执行3:. file1
执行4:source file1
多种执行方式的区别:
bash file1和sh file1,是子shell;. file1和source file1,是本shell。
bash file1和sh file1都是在新的Shell环境中执行脚本,而. file1和source file1是在当前Shell环境中执行脚本。
shell解释器在哪
cat /etc/shells或chsh -I
变量
简介
shell变量:用一个固定的字符串去表示不固定的内容,便于修改。
自定义变量
简述:用户自定义变量是最常用的变量类型,其特点是变量名和变量值都是由用户自由定义的。
学习要点:
定义变量:变量名=变量值
引用变量:$变量名
查看变量:echo$变量名
取消变量:unset 变量名
定义变量:
该如何定义变量呢?很简单,只需执行”变量名=变量值"命令即可,不过要遵守变量定义规则。
例:[root@localhost ~]# name="xulei 666"
变量调用
当我们需要提取变量中的内容时,需要在变量名之前加入"$" 符号。那么最简单的变量调用就是通过echo 命令输出变量的值。
定义变量name:
[root@localhost ~]# name="xulei 666"
输出变量name的值:
[root@localhost ~]# echo $name
xulei 666
错误定义示范:
变量的定义就是这么简单,但是如果不遵守变量定义规则,就会报错。比如:
- 变量名不能以数字开头
- 等号左右两侧不能有空格
- 变量的值如果有空格,必须用引号包含
重复定义变量
重复定义变量会进行变量叠加。例如:
#定义变量aa的值是123
[root@localhost ~]# aa=123
#重复定义变量aa的值是源aa的值加上456
[root@localhost ~]# aa="$aa"456
#调用变量aa,发现值已经变成了123456
[root@localhost ~]# echo $aa
123456
#在进行变量叠加时,也可以使用$(变量名)格式
[root@localhost ~]# aa=$(aa)789
[root@localhost ~]# echo $aa
123456789
注意:在进行变量叠加时,变量名需要用双引号或$包含。
变量查看
我们可以通过echo命令查询已经设定的变量的值,这种查询是已知变量名查询变量值。但是如果我不知道变量名,那么可以查询系统中已经存在的变量吗?
[root@localhost ~]# set
变量删除
要想删除自定义变量,可以使用unset 命令。命令格式如下:
[root@localhost~]# unset 变量名
这条命令执行之后,再查询变量,就会发现这个变量已经为空了。
[root@localhost ~]# unsetname
[root@localhost ~]# echo $name
输出是空的
示例
使用变量前:
需求 :
编写测试主机在线的脚本。当主机在线提示在线,当主机不在线提示不在线。
编写脚本 :
[root@localhost ~]vim ping.sh
ping -c1 192.168.100.10 &> /dev/null && echo 192.168.100.10up || echo 192.168.100.10down
注释:
- &&和||是三目表达式
- &&前面的命令成功。执行后面的命令
- ||前面的命令失败。执行后面的命令
授权脚本:[root@localhost ~]#chmod +x ping.sh
执行脚本:[root@localhost ~]#./ping.sh
思考:如果更换测试IP。需要修改脚本的哪些部分? 需要修改三个部分
使用变量后:
编写脚本:
[root@localhost ~]vim ping.sh
#!/bin/bash
ip=192.168.100.10
ping -c1 $ip &>/dev/null && echo $ip up || echo "$ip down"
授权脚本:[root@localhost ~]# chmod +x ping.sh
执行脚本:[root@localhost ~]# ./ping.sh
思考:添加变量后,修改一处即可。
交互定义变量
read 从键盘读入变量值
赋值方式: read 变量名
示例:
read -p "请输入您测试的IP地址 : "ip
ping -c1 $ip &>/dev/null && echo " $ip up" || echo "$ip down"
注意事项:3种引号(定义或引用变量时注意事项)
(" " 弱引用 ' ' 强引用 ` ` 优先执行)
双引号1
[root@localhost ~]# schoo=1000 phone
bash:phone:未找到命令
[root@localhost ~]# schoo="1000 phone"
[root@localhost ~]# echo $schoo
1000 phone
双引号2
[root@localhost ~]# schoo=$schoo is good
bash:is:未找到命令
[root@localhost ~]# schoo="$schoo is good"
[root@localhost ~]# echo $schoo
1000 phone is good
单引号
[root@localhost ~]# schoo='$schoo 666'
[root@localhost ~]# echo $schoo
$schoo 666
反引号
[root@localhost~]# schoo=`date`
[root@localhost ~]# echo $schoo
2020年 05月 06日 星期三 14:57:13 CST
注意
变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。不能使用标点符号。
不能使用bash里的关键宇(可用help命令查看保留关键字)。
起变量名,请使用五个字母以上。
整数运算
方法一:expr
语法:
expr 1 + 2 expr $num1 + $num2
+加 -减 \*乘(*是任意字符,使用\转义一下。) /除 %取余
案例:
需求:运算学员的成绩总分
制作脚本:[root@localhost ~]# vim sum.sh
#!/bin/bash
read -p "请输入您的第一门成绩:"number1
read -p "请输入您的第二门成绩:"number2
echo -n "总成绩是:"
expr $number1 + $number2
授权脚本:[root@localhost ~]# chmod +x sum.sh
测试脚本:[root@master1 ~]#./sum.sh
请输入您的第一门成绩:60
请输入您的第二门成绩:70
总成绩是:130
方法二:$(())
语法:
echo $(($num1+$num2))
echo $((num1+num2))
echo $((5-3*2))
echo $((2**3)) //(幂)2的3次方
方法三:$[ ]
语法:
echo $[5+2] + - * \ %
echo $[5**2]
方法四:let
示例:
let sum=2+3; echo $sum
let i++; echo $i
小数运算
需提前安装计算器程序bc (yum install -y bc)
例:
echo "2*4" | bc
echo "2^4" | bc
echo "scale=2;6/4" | bc
(bc:交互运算器
scale=2 保留小数点后面两位)
环境变量
前言:自定义变量,只能再当前shell生效。其他shell是不生效的。即,你的变量只能你用。那如果有些变量,需要所有的用户都能够使用,那该怎么办呢?
定义环境变量:
- 直接声明 方法一 export back_dir2=/home/backup
- 转换声明 方法二 export back_dir1 将自定义变量转换成环境变量
变量作用范围:在当前shell和子shell有效
- 想使变量在当前用户登陆后一直生效,可以将变量放到~/.bash_profile
- 想使变量在所有用户登陆后一直生效,可以将变量放到/etc/profile
示例:
[root@localhost ~]# abc=123
[root@localhost ~]# def=456
[root@localhost ~]# bash
[root@localhost ~]# echo $abc
[root@localhost ~]# echo $def
[root@localhost ~]# exit
[root@localhost ~]# export abc
[root@localhost -]# bash
[root@localhost~]# echo $abc
123
[root@localhost~]# echo $def
位置变量和预定义变量
位置变量语法:
命令 参数1 参数2 参数3 ...9以后特殊定义
位置变量 $0 $1 $2 $3 $4 $5 $6 $7 $8 $9...
($0:表示命令本身,即命令的名称或路径。
$1、$2、$3、...:表示命令后的位置参数,依次表示第一个、第二个、第三个参数的值,以此类推。
$9:表示第九个位置参数的值。
$10、$11、...:表示第十个、第十一个位置参数的值,以此类推。
需要注意的是,当位置参数的值超过9时,需要使用花括号将数字括起来,以避免与其他字符混淆。例如,${10}表示第十个位置参数的值。)
示例:
需求:制定脚本程序,用户自行输入两门学科的成绩(整数),自动算出平均分.
制作脚本:
[root@localhost ~]# vim avg.sh
#!/bin/bash
echo "($1+$2)/2" |bc
[root@localhost ~]# chmod a+x avg.sh
测试脚本:
[root@localhost ~]#./avg.sh 88 77
82
使用read读取变量完成需求:
#!/bin/bash
read -p "请输入您的第1门成绩:" num1
read -p "请输入您的第2门成绩:" num2
echo -n "您的平均成绩是:"
echo "($num1+$num2)/2" |bc
(-n选项是echo命令的一个参数,用于指定不要在输出末尾添加换行符。
通常情况下,echo命令会在输出文本后自动添加一个换行符,以使输出显示在新的一行。但是,当使用-n选项时,echo命令将不会在输出末尾添加换行符,而是保持在同一行。)
总结
- 位置变量就是$1,$2,$3,$4
- 位置变量预先已经被定义过了。
- 用户使用时,必须携带参数。
- 位置变量不是程序设计的唯一方法。比如read也可以。
预定义变量
$0 脚本名/程序名
$* 所有的参数
$# 参数的个数
$? 上一个程序的返回值(0是成功,非零失败)
$$ 程序的PID
示例:
定义脚本:
[root@localhost ~]# vim avg.sh
#/bin/bash
echo "($1+$2)/2" |bc
echo "该程序名为$0"
echo"该程序使用了$# 个参数”
echo"该程序的参数如下:$*"
调用脚本:
[root@localhost ~]#./avg.sh 60 50
55
该程序名为./avg.sh
该程序使用了2个参数
该程序的参数如下:60 50
注意:
这两类变量,在设计系统时就已经定义好了。需要使用时,直接调用即可。
课后题
编写自动创建用户并设置初始密码的脚本。
#!/bin/bash
read -p "please input username:" name
useradd $name
echo "123456" | passwd --stdin $name &> /dev/null
echo "$name create finished,the password is 123456"
用位置变量编写:
#!/bin/bash
useradd $1
echo "$2" | passwd --stdin $1 &> /dev/null
echo "$1 create finished,the password is $2"
编写脚本,配置本地yum源
#!/bin/bash
mount /dev/cdrom /mnt &> /dev/null
mv /etc/yum.repos.d/* ~
cat /etc/yum.repos.d/yum.repo
[local]
name=localyum
baseurl=file:///mnt
enabled=1
gpgcheck=0
EOF
yum repolist all