shell变量
1.什么是变量
变量是shell中传递数据的一种方法
就是用一个固定的字符串去表示不固定的值,便于后续引用
2.变量命名规范
变量定义命名:大写、小写字母,下划线组成,尽量字母开头,最好具备一定意义
变量定义语法:变量名=变量值,等号是赋值,等号两边不能有空格
定义的变量不要与系统命令出现冲突
3.变量定义
用户自定义变量
用户自定义变量,在当前shell有效
定义变量,变量名=变量值,不能出现-
(横杠)命名
定义变量有空格时,必须使用双引号
var="hello shell"
引用变量
$变量名 或者 ${变量名}
例:
不加{}
的话,系统会认为$后面的一整段都是变量名,就不会输出我们想要的结果
引用变量时候,""双引号属于弱引用,''单引号属于强引用
在使用的时候要注意,双引号里的变量名是可以被解析的,单引号的不被解析,
所以引号中的内容包含变量就要用双引号
系统环境变量(全局可用)
系统环境变量,在当前shell与子shell有效
系统已经定义好的变量,可以直接引用
输入env
可以进行查看
例:
#!/bin/bash
echo "用户的加目录:$HOME"
echo "当前主机名:$HOSTNAME"
echo "当前所在目录:$PWD"
echo "当前SSH的连接情况:$SSH_CONNECTION"
人为定义环境变量,可以通过export 变量
,将自定义的变量转换成环境变量
当我们在父shell中定义了一个变量,在子shell中没有定义是无法引用这个变量的,因为子shell会使用另外的bash执行,就访问不到父shell定义的变量,在想要引用这个变量,可以通过export 转换成环境变量后进行引用。
例:
查看环境变量
预定义变量(Shell规定的)
cat var.sh
#!/bin/bash
echo "#当前shell脚本的文件名: $0"
echo "#第1个shell脚本位置参数:$1"
echo "#第2个shell脚本位置参数:$2"
echo "#第3个shell脚本位置参数:$3"
echo "#所有传递的位置参数是: $*"
echo "#所有传递的位置参数是: $@"
echo "#总共传递的参数个数是: $#"
echo "#当前程序运行的 PID 是: $$"
echo "#上一个命令执行的返回结果: $?" 0表示没有错误,其他任何值表明有错误
演示:
案例1:
通过位置变量创建 Linux 系统账户及密码,
执行 user.sh username password
我们日常手动创建流程如下
useradd test #创建用户test
echo "1234qwe" |passwd --stdin test 设置test的密码为123qwe
利用预定义变量,可以转换成以下脚本
#!/usr/bin/bash
# $1表示执行脚本后面跟的第一个参数 用户名
# $2表示执行脚本后面跟的第二个参数 密码
useradd $1
echo "$2" | passwd --stdin $1
执行脚本,成功创建用户以及设置密码
案例2:
在前面创建用户的基础上,
能不能要求,必须输入两个参数,不能多,也不能少。
如果不是两个参数,则提示错误,然后退出脚本。
如果是两个参数,就创建用户及密码
$#可以知道用户传递了几个参数。
如何控制,需要借助一下if语句。 如果满足,就怎么样,否则就怎么样。
cat var2.sh
#!/usr/bin/bash
# $1表示执行脚本后面跟的第一个参数 用户名
# $2表示执行脚本后面跟的第二个参数 密码
#先判断用户输入的参数个数是否符合我们的预期,如果符合,则顺序执行,不符合直接退出脚本。
# ne是不等于的意思
#成立则执行then后面的语句,不成立则不执行then后面的语句。
if [ $# -ne 2 ];then
echo "请输入正常的参数 [ username && password ] Parameters...."
exit
fi
useradd $1
echo "$2" | passwd --stdin $1
执行脚本,成功创建用户以及设置密码
4.交互传递参数 read
#!/bin/bash
read -p "输入用户名" user
#-p打印信息
read -n6 -s -t5 -p "输入密码" pw
#-p打印信息,-t5限时5秒,-n6指定6个字符个数,-s不回显,当输入密码时候不会显示,但实际上已经输入了
echo "你输入的用户名是:$user,输入的密码是:$pw" #引用
案例1:
使用read模拟Linux登陆页面
1.想办法提取关键字,CentOS Linux 7 (Core)
hostnamectl | awk -F ':' '/Operating System/ {print $2}'
思路梳理:
1.利用命令hostnamectl
查询系统主机名相关设置
2.然后用awk去匹配Operating System这一行
awk '/Operating System/'
hostnamectl |awk '/Operating System/'
3.以:为分隔符,打印 Operating System: CentOS Linux 7 (Core)这一行的第二列,就得到了想要的结果。
hostnamectl |awk -F ':' '/Operating System/ {print $2}'
2.Kernel 部分信息获取
思路梳理:
1.使用uname
的-r
与-m
参数获取到以下信息,然后拼接在一起即可
整理成脚本,最终就得到了想要的效果
$()
括号内部通常是一个shell命令,在执行脚本之前,会先执行括号里的命令,相当于函数调用
#!/bin/bash
echo $(hostnamectl |awk -F ':' '/Operating System/ {print $2}') #输出第一行信息
echo "Kernel $(uname -r) on an $(uname -m)" #将获取到的参数拼接后,作为第二行信息输出
echo "" #输出空行
read -p "$HOSTNAME login:" user
read -s -p "password" pw
echo "你输入的用户名:$user,输入的密码:$pw"
案例2:
模拟编写一个备份的脚本,需要用户传递2个参数,一个要备份的源路径,一个备份到的目标路径。
思路梳理:
1.你要备份什么 (要备份的路径) 存储为一个变量src
2.你要备份到哪里 (要备份到的目标路径) 存储为一个变量dest
3.提示用户:你确定要备份吗? [ y | n ] 将用户返回的值,存储为一个变量 action
最后去判断一下,判断他是不是要备份,如果是 y ,调用cp命令进行备份 cp $src $dest
#!/bin/bash
read -p "输入你要备份的路径:" src
read -p "输入你要备份到的路径:" dest
read -p "你确定将 $src 备份到 $dest 吗?[ y | n ]" action
if [ $action == "y" ];then
cp -rp $src $dest
echo "$src 成功备份到 $dest "
fi
执行脚本,查看结果
案例3:
使用read方式编写一个探测主机存活的脚本,需要用户传递测试的IP地址
思路梳理:
先让用户输入一个IP地址 read -p "输入要探测的主机IP地址:" ip
再去ping用户输入的IP地址 ping -c1 -w1 $ip &> /dev/null
根据ping返回的结果判定主机是否存活
ping -c1 -w1
中-c1是指ping的次数,-w是指timeout时间,指定期限,超过期限认定不通
&> /dev/null
是指标准输出和错误输出都输出到/dev/null,不显示
#!/bin/bash
read -p "输入要探测的主机IP地址:" ip
ping -c1 -w1 $ip &> /dev/null
if [ $? -eq 0 ];then #如果上一个命令执行返回的结果等于0,表示没有错误,就代表主机存活
echo "主机 $ip 存活"
else #如果上一个命令执行返回的结果不等于0,表示有错误,就代表主机不存活
echo "主机 $ip 不存活"
fi
案例4:
使用read编写一个修改系统主机名的脚本。
思路梳理:
1.打印当前系统的主机名称:
oldhostname=$(hostname)
echo "当前主机名为:$oldhostname"
2.提示用户输入新的主机名称:read -p "输入新的主机名:" newhostname
3.询问用户是否确定修改,依据用户返回的结果进行判定
4.如果确定,则直接通过hostnamectl set $newhostname
变更,否则退出即可。
#!/bin/bash
oldhostname=$(hostname)
echo "当前主机名为:$oldhostname"
read -p "输入新的主机名:" newhostname
read -p "确定将 $oldhostname 变更为 $newhostname 吗?[ y | n ]" action
if [ $action == "y" ];then
hostnamectl set-hostname $newhostname
echo "主机名变更成功,当前主机名为:$newhostname"
fi