shell之变量
1、概述
shell变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
有效的shell变量名示例如下:
1
2
3
4RUNOOB
LD_LIBRARY_PATH
_var
var2无效的变量命名如下:
1
2?var=123
user*name=runoob
2、变量定义
①自定义变量。
定义变量:变量名=变量值 ,变量名必须以字母或者下划线开头,区分大小写。
引用变量:
$变量名
或者${变量名}
。查看变量:echo $变量名。
取消变量:unset 变量名。
eg:1:判断通过变量定义的主机是否能ping通。
1
2
3
4
5
6
7
8
9!/usr/bin/bash
ip=www.baidu.com
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ]; then
echo "$ip is up."
else
echo "$ip is down."
fieg2:判断通过键盘读入定义的主机是否能ping通。
1
2
3
4
5
6
7
8
9!/usr/bin/bash
read -p "Please input a ip:" ip
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ]; then
echo "$ip is up."
else
echo "$ip is down."
fieg2:判断通过位置变量定义的主机是否能ping通。
1
2
3
4
5
6
7
8
9
10!/usr/bin/bash
$1 位置变量
ping -c1 $1 &>/dev/null
if [ $? -eq 0 ]; then
echo "$1 is up."
else
echo "$1 is down."
fi
运行命令:bash ./test.sh www.baidu.com
②环境变量。
定义变量:
export 变量名=变量值
;export 变量名
将自定义变量转换成环境变量。引用环境变量:
$变量名
或者${变量名}
。查看环境变量:
echo $变量名
;env
。取消环境变量:unset 变量名。
eg1:测试变量作用范围。
1
2
3
4
5
6
7
8
9
10
11
12[root@centos7 shell]# ip1=1.1.1.1
[root@centos7 shell]# export ip2=2.2.2.2
[root@centos7 shell]# vim test.sh
[root@centos7 shell]# cat test.sh
echo "ip1 is: $ip1"
echo "ip2 is: $ip2"
[root@centos7 shell]# bash ./test.sh # 在子shell中执行
ip1 is:
ip2 is: 2.2.2.2
[root@centos7 shell]# . test.sh # 在当前shell中执行
ip1 is: 1.1.1.1
ip2 is: 2.2.2.2eg2:不定义环境变量(父子shell都能使用的变量),因为可以在当前脚本中使用另外一个脚本,使得变量共享。
1
2
3
4
5
6
7
8
9
10
11
12[root@centos7 shell]# vim public.sh
[root@centos7 shell]# cat public.sh
ip3=3.3.3.3
dir_path=/etc
[root@centos7 shell]# vim test2.sh
[root@centos7 shell]# cat test2.sh
. public.sh #这里可以是相对路径,也可以是绝对路径,.表示在当前shell执行
echo "ip3 is: $ip3"
echo "dir_path is: $dir_path"
[root@centos7 shell]# bash test2.sh
ip3 is: 3.3.3.3
dir_path is: /etc
③预定义变量。
符号 说明 $0 脚本名 $*、$@ 所有的参数 $# 参数的个数 $$ 当前进程的PID $! 上一个后台进程的PID $? 上一个命令的返回值,0表示成功 eg1:测试指定文件中的ip地址是否能ping通。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31[root@centos7 shell]# cat test3.sh
!/usr/bin/bash
提示方法,如果用户没有加参数
if [ $# -eq 0 ];then
echo "uasge: `basename $0` file" #basename只显示最后一个名字,eg:basename /home/wangji/cc,只显示cc
exit
fi
#判断是否为文件
if [ ! -f $1 ];then
echo "error file!"
exit
fi
for ip in `cat $1`
do
ping -c1 -W1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "$ip is up"
else
echo "$ip is down"
fi
done
[root@centos7 shell]# cat test.txt
1.1.1.1
2.2.2.2
3.3.3.3
[root@centos7 shell]# ./test3.sh test.txt
1.1.1.1 is up
2.2.2.2 is down
3.3.3.3 is down
变量匹配。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[root@centos7 shell]# url=www.sina.com.cn
[root@centos7 shell]# echo ${#url} # 获取变量值的长度
15
[root@centos7 shell]# echo ${url} # 标准查看
www.sina.com.cn
[root@centos7 shell]# echo ${url#*.} # 从前往后,最短匹配
sina.com.cn
[root@centos7 shell]# echo ${url##*.} # 从前往后,最长匹配,贪婪匹配
cn
[root@centos7 shell]# echo ${url%.*} # 从后往前,最短匹配
www.sina.com
[root@centos7 shell]# echo ${url%%.*} # 从后往前,最长匹配,贪婪匹配
www
[root@centos7 shell]# echo ${url#a.} # 错误的结果
www.sina.com.cn
[root@centos7 shell]# echo ${url#*sina.} # 正确的结果
com.cn
3、变量赋值
①显示赋值:变量名=变量值。
1
2
3
4
5
6
7
8
9
10` `是命令替换,换等价于$(),其中的shell命令会被先执行
[root@centos7 shell]# today=`date +%F`
[root@centos7 shell]# echo today
today
[root@centos7 shell]# today=`date +%F`
[root@centos7 shell]# echo $today
2021-08-09
[root@centos7 shell]# today2=$(date +%F)
[root@centos7 shell]# echo $today2
2021-08-09②read从键盘读入变量值。
1
2
3
4read 变量名
read -p "提示信息:" 变量名 # -p:"提示信息",在等待read输入时,输出提示信息
read -t 5 -p "提示信息:" 变量名 # -t:秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间
read -n 2 变量名 # -n:字符数:read命令只接收指定的字符数就会执行1
2
3
4
5
6
7
8
9
10
11[root@centos7 shell]# read ip
1.1.1.1
[root@centos7 shell]# echo $ip
1.1.1.1
[root@centos7 shell]# read -p "Please input: " ip
Please input: 2.2.2.2
[root@centos7 shell]# echo $ip
2.2.2.2
[root@centos7 shell]# read -n 2 name
ab[root@centos7 shell]# echo $name
ab定义或引用变量时的注意事项:
1
2
3
4
5[root@centos7 shell]# school=longhu
[root@centos7 shell]# echo "$school is good" # " "弱引用
longhu is good
[root@centos7 shell]# echo '$school is good' # ' '强引用
school is good
4、变量运算
①整数运算。
方法一:expr。
1
2
3
4
5
6
7
8[root@centos7 shell]# num1=10
[root@centos7 shell]# num2=20
[root@centos7 shell]# sum=`expr $num1 + $num2`
[root@centos7 shell]# echo $sum
30
[root@centos7 shell]# sum=`expr $num1 \* $num2`
[root@centos7 shell]# echo $sum
200方法二:$(())。
1
2
3
4
5
6
7
8
9[root@centos7 shell]# num1=1
[root@centos7 shell]# num2=2
[root@centos7 shell]# sum=$((1+2));echo $sum
3
[root@centos7 shell]# echo $((5-3*2))
-1
[root@centos7 shell]# echo $(($num1+$num2))
3
[root@centos7 shell]# echo $((2**3))eg:测试当前系统内存使用百分比。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27[root@centos7 shell]# cat memuse.sh
!/usr/bin/bash
mem_used=`free -m |grep '^Mem:' |awk '{print $3}'`
mem_total=`free -m |grep '^Mem:'|awk '{print $2}'`
mem_percent=$((mem_used*100/mem_total))
echo "当前内存使用的百分比:$mem_percent"
[root@centos7 shell]# bash -vx memuse.sh # 使用调试方式去执行脚本
!/usr/bin/bash
mem_used=`free -m |grep '^Mem:' |awk '{print $3}'`
free -m |grep '^Mem:' |awk '{print $3}'
++ grep '^Mem:'
++ awk '{print $3}'
++ free -m
+ mem_used=812
mem_total=`free -m |grep '^Mem:'|awk '{print $2}'`
free -m |grep '^Mem:'|awk '{print $2}'
++ grep '^Mem:'
++ awk '{print $2}'
++ free -m
+ mem_total=1980
mem_percent=$((mem_used*100/mem_total))
+ mem_percent=41
echo "当前内存使用的百分比:$mem_percent"
+ echo 当前内存使用的百分比:41
当前内存使用的百分比:41
方法三:$[]。
1
2
3
4[root@centos7 shell]# echo $[5+2]
7
[root@centos7 shell]# echo $[5*2]
10方法四:let。
1
2
3
4[root@centos7 shell]# let num=2+3;echo $sum
3
[root@centos7 shell]# let i++;echo $i
1
②小数运算。
1
2
3
4
5
6
7在shell中做小数运算,可以借助bc或者awk工具
[root@centos7 shell]# awk 'BEGIN{print 1/2}'
0.5
[root@centos7 shell]# echo "print 5.0/2" |python
2.5
[root@centos7 shell]# echo "scale=2;6/4" |bc # 保留小数点后2位
1.50
5、索引与切片
eg:
1
2
3
4
5
6
7[root@centos7 shell]# url=www.sina.com.cn
[root@centos7 shell]# echo ${url:0:5} # 从第0个取,取5个
www.s
[root@centos7 shell]# echo ${url:5:5} # 从第5个取,取5个
ina.c
[root@centos7 shell]# echo ${url:5} # 从第5个开始取
ina.com.c
6、变量替换
eg1:
1
2
3
4
5
6
7
8
9[root@centos7 shell]# url=www.sina.com.cn
[root@centos7 shell]# echo ${url}
www.sina.com.cn
[root@centos7 shell]# echo ${url/sina/baidu} # 将sina替换成baidu
www.baidu.com.cn
[root@centos7 shell]# echo ${url/n/N} # 将n替换成N
www.siNa.com.cn
[root@centos7 shell]# echo ${url//n/N} # 将所有n替换成N,//表示贪婪匹配
www.siNa.com.cNeg2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14${变量名-新的变量值}
变量没有被赋值:会使用"新的变量值"替换
变量有被赋值(包括空值):不会被替代
[root@centos7 shell]# unset var1
[root@centos7 shell]# echo ${var1}
[root@centos7 shell]# echo ${var1-aaa}
aaa
[root@centos7 shell]# var2=111
[root@centos7 shell]# echo ${var2-bbb}
111
[root@centos7 shell]# var3=
[root@centos7 shell]# echo ${var3-ccc}eg3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14${变量名:-新的变量值}
变量没有被赋值(包括空值):都会使用“新的变量值”替代
变量有被赋值:不会被替代
[root@centos7 shell]# unset var1
[root@centos7 shell]# unset var2
[root@centos7 shell]# unset var3
[root@centos7 shell]# var2=
[root@centos7 shell]# var3=111
[root@centos7 shell]# echo ${var1:-aaaa}
aaaa
[root@centos7 shell]# echo ${var2:-aaaa}
aaaa
[root@centos7 shell]# echo ${var3:-aaaa}
111eg4:
1
2
3
4
5
6
7
8
9其它例子
echo ${var3+aaa}:假如var3设为空值或非空值,均使用aaa作传回值。(没设定时不作处理)
echo ${var3:+aaa}:若var3为非空值,则使用aaa作传回值。(没设定及空值时不作处理)
echo ${var3=aaa}:若var3没设定,则使用aaa作传回值,同时将var3赋值为aaa。(空值及非空值时不作处理)
echo ${var3:=aaa}:若var3没设定或为空值,则使用aaa作传回值,同时将var3赋值为aaa。(非空值时不作处理)
echo ${var3?aaa}:若var3没设定,则将aaa输出出至STDERR。(空值及非空值时不作处理)
echo ${var3:?aaa}:若var3没设定或为空值,则将aaa输出至STDERR。(非空值时不作处理)