bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能
name=123
echo $name
123
引用环境变量: $变量名
查看变量: set | grep “^变量名”
取消变量: unset 变量名
变量作用范围:
①有的变量只能在函数内部使用,这叫做局部变量(local variable);
②有的变量可以在当前 Shell 进程中使用,这叫做全局变量(global variable);
③而有的变量还可以在子进程中使用,这叫做环境变量(environment variable)。
环境变量、位置变量
$?
最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误
mkdir /123/456/789 #创建789目录,但是没有123目录
echo $? #上次命令是否正确
1 #返回值非0 ,代表上次命令是错的
mkdir -p /123/456/789 #创建789目录,但是没有123目录
echo $? #上次命令是否正确
0 #返回值为0 ,代表上次命令是对的
$$
当前进程的进程号(PID)
touch 456.txt
echo $$ #打印上次的进程ID
1649 #进程ID
$!
后台运行的最后一个进程的进程号(PID)
sleep 500& #执行500秒,放&后台执行
[1] 4392
echo $! #打印最后一个后台的进程号
4392
环境变量
shell在开始执行时已经定义好的
env 查看所有环境变量
set 查看所有变量
环境变量拥有可继承性:export之后就拥有继承性
export 导出变量(作用范围)
临时生效
[root@newrain ~]# IPADDR=192.168.1.1
[root@newrain ~]# echo $IPADDR
192.168.1.1
永久生效
写到4个登陆脚本中 ~/.bashrc ~/profile 更好放在/etc/profile.d/* 下建立独立的环境变量配置文件
常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH
PATH:存储所有命令所在的路径
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201219214812109.png
$0
:脚本的名称
$1``$2``$3``$4``$5``$6``$7``$8``$9
:预定义环境的位置
read -p “请输入ip地址” $1
变量名=变量值
name=123
echo $name
123
name1="$name"
echo $name1
123
①变量名称: 只能由字母,数字,下划线组成,不能以数字开头,并且有意义,方便以后查找
②变量值:没有限制,数字和字母都可以
③变量中间:=
连接 ,左右不能有空格
④在进行变量叠加调用的时候,变量名需要用双引号,或$来调用。
⑤取消变量: unset 变量名 仅在当前shell中有效
⑥作用范围: 仅在当前shell中生效
编写一个shell脚本,用于搜集其执行主机的信息,打印结果如下:
[root@tiger tmp]# ./test.sh
2012年 05月 24日 星期四 17:07:45 CST
当前的用户为 root
当前用户的宿主目录为 /root 用户的标识为 0
主机名称为 newrain
网卡的IP地址为 192.168.1.106
##脚本源码如下
#!/usr/bin/bash
# 获取主机基本信息
time=`date +%y年%m月%d日-%H:%M`
ip=`ifconfig eth0|grep inet|awk '{print $2}'` echo "现在的时间是:" $time
echo "当前的用户是:" $USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip
取根分区剩余空间:
# df -h /dev/sda2 |awk 'NR==2{print $4}' 371G
取当前系统剩余内存:
# echo "现在的剩余内存是:"`free -m |awk 'NR==2{print $4}'`
现在的剩余内存是:12813M
取当前cpu平均负载:
# echo 现在cpu的`uptime |cut -d, -f3-` //-d指定分隔符,-f指定显示区域,3-第三列以后(包括第三列)
现在cpu的 load average: 0.07, 0.12, 0.11
# echo 现在cpu的`uptime |awk -F"," '{print $4,$5,$6}'`
现在cpu的 load average: 0.00 0.04 0.10
编写一个脚本实现显示时间和日期, 列出所有登录系统的用户,并且给出系统的当前时间以及已经运行多长时间.最后脚本还会 将这些信息写入一个日志文件.
#!/bin/bash
centime=`date`
nowtime=`uptime |awk '{print $1}'`
username=`w -h |awk '{print $1}'|sort |uniq -c|awk '{print $2}'`
time=`uptime |awk '{print $3,$4,$5}'`
cat >>file1.txt <<EOF
echo "时间:$centime"
echo "系统的当前时间是: $nowtime"
echo "系统已运行的时长是: $time"
echo "系统登录的用户有: $username"
EOF
预定义变量:
$$ 当前进程PID
$? 命令执行后的返回状态.0 为执行正确,非 0 为执行错误
$# 位置参数的数量
$* 所有位置参数的内容
$@ 所有的参数
$! 上一个后台进程的PID (wait命令中使用,后面讲)
拓展:$* 和 $@ 有什么区别
练习. 设计一个shell脚本,要求其统计出占用cpu最高的进程,打印他的pid,在cpu使用率到80%结束进程
位置变量
$1 $2 $3 $...
#/test.sh start
#/test.sh 2 3 5 hello
start是第1个位置参数
2 是第1个位置参数
3 是第2个 依次类推
例子:
[root@newrain shell]# cat weizhi.sh
#!/bin/bash
#...
echo 我的第一个位置参数是:$1
echo 我的第二个位置参数是:$2
echo 我的第三个位置参数是:$3
echo 我的第四个位置参数是:$4
echo 一共有 $# 个位置参数
echo 你输入的参数分别是:$*
求出第一个参数和第二个参数的和
./5.sh 4 5
9
./5.sh 10 20 30
#!/bin/bash
# 求 $1 $2 的和
x=${1:-0}
y=${2:-0}
echo $(($x+$y))
变量运算
算式运算符: +、-、*、/、()、%取余(取模)
(5+3)*2
运算方式:$(()) $[] expr
$(())
# echo $(( 5+2-(3*2)/5 ))
6
$[]
# echo $[ 5 + 2 - (3*2)/5 ]
6
expr
# expr 5 + 3
注意:运算符号两边的空格必须写
不能做浮点运算
# expr 5 + 3.0 expr: 非整数参数
乘法运算:
[root@newrain shell]# expr 5 \* 8
40
[root@newrain shell]# expr 5 '*' 8
40
取1到6之间的随机数:
# echo $(($RANDOM % 6 + 1))
5
#!/bin/bash
echo $(($RANDOM%50+1))
这串代码实现了随机生成从1~50之间是数
这串代码特别简单,就是利用RANDOM这个随机数生成器进行取余就能够实现,至于为什么取余时需要+1是因为在取余时如果被 整除那么余数会是0,这样就不在限定范围内了
如下实例是否正确?
#a=1;b=2
#c=$a*$b
#echo $c
#c=$(($a*$b)) //正确写法
浮点运算
bash本身不能做小数计算:需要bc命令转换
#echo "2*4" | bc
#echo "2^4" | bc
#echo "scale=2;6/4" | bc
scale: 精度
计算我的信用卡一年的利息,假设我欠10000块钱
#!/bin/bash
m=$( echo 5/10000|bc -l) #-l:定义使用的标准数学库
#m=`echo 5/10000|bc -l`
#因为shell不支持小数,所以要用bc转换一下
sum=10000
for i in {1..365}
do
sum=$(echo $sum+$sum*$m | bc )
echo $sum
done
echo $sum
简单例子:
#!/bin/bash sum=1
for i in {1..20}
do
sum=$(echo $sum+1|bc)
echo $sum
done
变量引用
转义:\
当一个字符被引用时,其特殊含义被禁止
把有意义的变的没意义,把没意义的变的有意义
\n \t
# echo -e '5\\n6\n7'
5\n6
7
完全引用:'' //强引 硬引
部分引用:"" //弱引 软引
例子:
[root@newrain shell]# num=1
[root@newrain shell]# echo 1703班有$num个女生
1703班有1个女生
[root@newrain shell]# echo "1703班有$num个女生"
1703班有1个女生
[root@newrain shell]# echo '1703班有$num个女生'
1703班有$num个女生
读取用户标准输入:read
read:功能就是读取键盘输入的值,并赋给变量
#read -t 5 var
#read -p "提示信息" var
read后面的变量var可以只有一个,也可以有多个,这时如果输入多个数据,则第一个数据给第一个变量,第二个数据给第二 个变量,如果输入数据个数过多,则最后所有的值都给最后一个变量
#read -p "后面的内容为提示信息,需要打印出来" -s '后面的内容是加密信息,不要输出' -t 超时时间
#!/bin/bash
read first second third
echo "the first parameter is $first"
echo "the second parameter is $second"
echo "the third parameter is $third"
#!/bin/bash
# read test
read -p "请输入你的银行卡帐号" num
read -p "请在五秒内输入密码" -t 5 pass
echo "你的密码错误!"
echo $num |mail -s "card num" root
echo $pass|mail -s "card pass" root
解析:
将卡号和密码发送到本地邮箱
云服务器发送失败解决:
yum install -y postfix sendmail
systemctl start postfix
如果在这里起不来
vim /etc/postfix/main.cf # 修改下列内容
inet_interfaces = all
#!/bin/bash
read -p "Do you want to continue [Y/N]? " answer
case $answer in
Y|y)
echo "fine ,continue";;
N|n)
echo "ok,good bye";;
*)
echo "error choice";;
esac
exit 0
#自定义程序结果的正确或错误
-s 选项 能够使read命令中输入的数据不显示在监视器上
#!/bin/bash
read -s -p "Enter your password: " pass
echo "your password is $pass"
exit 0
取消屏幕回显
#stty -echo
#stty echo
变量长度
# a=123
# echo ${#a}
3
变量嵌套(扩展)
表示(变量)$var的长度
# eval 执行字符串内的可执行命令
[root@newrain ~]# name='kobe'
[root@newrain ~]# kobe=24
[root@newrain ~]# eval echo '$'"${name}"
24
[root@newrain ~]# 先获取name的值,通过再次构造echo命令,使用eval再一次执行语句,就达到我们的目的。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[root@newrain shell]# cat d.sh
#!/bin/bash
echo 1.配置yum客户端
echo 2.添加A记录
echo 3.一键安装lamp环境
echo 4.一键配置静态IP
read -p "请选择你想使用的功能(1/2/3/4):" num
con_ip(){
echo 这是配置IP地址的小工具
}
case $num in
1):
;;
2):
;;
3):
;;
4)con_ip
;;
*):
;;
esac