一、Shell脚本的条件测试
1.条件测试方法综述
说明:
- [[]]中可以使用通配符等进行匹配
- &&、||、>、<等操作符可用于[[]],但不能用于[],在[]中一般用-a、-o、-gt、-lt替代操作符
2.test简单语法
test < 测试表达式 >
[root@codis-178 ~]# test -f n.sh && echo true || echo false
true
[root@codis-178 ~]# test -f n1.sh && echo true || echo false
false
(1)test命令-f选项
文件存在且为普通文件则表达式成立
[root@codis-178 ~]# test -f file && echo true || echo false
false
(2)test命令-z选项
如果测试字符串的长度为0,则表达式成立
[root@codis-178 ~]# test -f file && echo true || echo false
false
[root@codis-178 ~]# test -z "root" && echo 1 || echo 0
0
[root@codis-178 ~]# char="root"
[root@codis-178 ~]# test -z "$char" && echo 1 || echo 0
0
[root@codis-178 ~]# char=""
[root@codis-178 ~]# test -z "$char" && echo 1 || echo 0
1
3.[]语法
[ < 测试表达式> ]
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] && echo 1 || echo 0
0
(1)[]加-f选项
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] && echo 1 || echo 0
0
[root@codis-178 ~]# touch /tmp/oldboy.txt
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] && echo 1
1
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] && echo 0
0
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] || echo 0
[root@codis-178 ~]# rm -f /tmp/oldboy.txt
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] || echo 0
0
4.[[]]语法
[[ < 测试表达式 > ]]
[root@codis-178 ~]# [[ -f /tmp/oldboy.txt ]] && echo 1 || echo 0
0
(1)[[]]使用
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] || echo 0
0
[root@codis-178 ~]# touch /tmp/oldboy.txt
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] || echo 0
[root@codis-178 ~]# rm -f /tmp/oldboy.txt
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] || echo 0
0
二、文件测试表达式
1.文件测试表达式的用法
(1)普通文件
[root@codis-178 ~]# ls -l /tmp/oldboy.txt
-rw-r--r-- 1 root root 0 Jul 27 13:43 /tmp/oldboy.txt
[root@codis-178 ~]# [ -f /tmp/oldboy.txt ] && echo 1 || echo 0
1
(2)目录文件
[root@codis-178 ~]# mkdir oldgirl
[root@codis-178 ~]# [ -f oldgirl ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ -e oldgirl ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -d oldgirl ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -d oldboy ] && echo 1 || echo 0
0
(3)文件属性
[root@codis-178 ~]# ls -l oldboy
-rw-r--r-- 1 root root 0 Jul 27 13:46 oldboy
[root@codis-178 ~]# [ -r oldboy ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -w oldboy ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -x oldboy ] && echo 1 || echo 0
0
[root@codis-178 ~]# chmod 001 oldboy
[root@codis-178 ~]# ls -l oldboy
# 以下测试结果为root用户特殊情况
---------x 1 root root 0 Jul 27 13:46 oldboy
[root@codis-178 ~]# [ -w oldboy ] && echo 1 || echo 0
1
[root@codis-178 ~]# echo 'echo test' > oldboy
[root@codis-178 ~]# [ -r oldboy ] && echo 1 || echo 0
1
[root@codis-178 ~]# cat oldboy
echo test
[root@codis-178 ~]# [ -x oldboy ] && echo 1 || echo 0
1
[root@codis-178 ~]# ./oldboy
test
2.测试Shell变量
# 定义两个变量
[root@codis-178 ~]# file1=/etc/services;file2=/etc/rc.local
[root@codis-178 ~]# echo $file1 $file2
/etc/services /etc/rc.local
# 对单个文件变量进行测试
[root@codis-178 ~]# [ -f "$file1" ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -d "$file1" ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ -s "$file1" ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -e "$file1" ] && echo 1 || echo 0
1
# 对单个目录或文件进行测试
[root@codis-178 ~]# [ -e /etc ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -w /etc/services ] && echo 1 || echo 0
1
[root@codis-178 ~]# exit
logout
[xiaoda@codis-178 ~]$ [ -w /etc/services ] && echo 1 || echo 0
0
# 测试时变量的特殊写法(加引号的结果)
[root@codis-178 ~]# [ -f $oldgirl ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -f "$oldgir"l ] && echo 1 || echo 0
0
### 简单高效的测试文件
[root@codis-178 ~]# [ -x oldboy ] && echo 1
1
[root@codis-178 ~]# [ -f /etc ] || echo 0
0
3.特殊条件测试表达式
常用于替换if语句
语法格式:
[ 条件1 ] &&{
命令1
命令2
}
[[ 条件1 ]] &&{
命令1
命令2
}
test 条件1 &&{
命令1
命令2
}
[root@codis-178 ~]# cat 6_15.sh
[ -f /etc ] ||{
echo 1
echo 2
echo 3
}
[root@codis-178 ~]# sh 6_15.sh
1
2
3
三、字符串测试表达式
1.字符串测试操作符
说明:
- 一般字符串测试需要加双引号进行比较
- 比较符号两端要有空格
[root@codis-178 ~]# [ -n "abc" ] && echo 1 || echo 0
1
[root@codis-178 ~]# test -n "abc" && echo 1 || echo 0
1
[root@codis-178 ~]# test -n "" && echo 1 || echo 0
0
[root@codis-178 ~]# var="oldboy"
[root@codis-178 ~]# [ -n "$var" ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -n $var ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ -z "$var" ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ "abc" = "abc" ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ "abc" = "acd" ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ "$var" = "oldgirl" ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ "$var" = "oldboy" ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ "$var" != "oldgirl" ] && echo 1 || echo 0
1
注意:
字符串不加双引号,可能会导致判断上出现逻辑错误,即使语法没问题,但结果可能不对。
四、整数二元比较操作符
1.介绍
[root@codis-178 ~]# [ 2 > 1 ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ 2 < 1 ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ 2 \< 1 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ 2 = 1 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ 2 = 2 ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ 2 != 2 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ 2 -gt 1 ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ 2 -ge 1 ] && echo 1 || echo 0
1
[root@codis-178 ~]# [ 2 -le 1 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ 2 -lt 1 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [[ 5 > 6 ]] && echo 1 || echo 0
0
[root@codis-178 ~]# [[ 5 < 6 ]] && echo 1 || echo 0
1
[root@codis-178 ~]# [[ 5 -gt 6 ]] && echo 1 || echo 0
0
[root@codis-178 ~]# [[ 5 -lt 6 ]] && echo 1 || echo 0
1
2.整数变量测试实践
[root@codis-178 ~]# a1=98;a2=99
[root@codis-178 ~]# [ $a1 -eq $a2 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ $a1 -gt $a2 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ $a1 -lt $a2 ] && echo 1 || echo 0
1
[root@codis-178 ~]# [[ $a1 > $a2 ]] && echo 1 || echo 0
0
[root@codis-178 ~]# [[ $a1 < $a2 ]] && echo 1 || echo 0
1
五、逻辑操作符
1.介绍
2.逻辑操作符运算规则
-a和&&:两端都成立才为真
[root@codis-178 ~]# [ -f /etc/hosts -a -f /etc/services ] && echo 1 || echo 0
1
1 * 0 = 0 真
0 * 1 = 0 假
1 * 1 = 1 真
0 * 0 = 0 假
-o和||:两端都是0为假,一端不为0是真
[root@codis-178 ~]# [ 5 -eq 6 -o 5 -gt 3 ] && echo 1 || echo 0
1
1 + 0 = 1 真
1 + 1 = 2 真
0 + 1 = 1 真
0 + 0 = 0 假
3.逻辑操作符实践
# 使用多个[],并通过与或非进行混合测试
[root@codis-178 ~]# m=21;n=38
[root@codis-178 ~]# [ $m -gt 20 -a $n -lt 30 ] && echo 1 || echo 0
0
[root@codis-178 ~]# [ $m -gt 20 ] || [ $n -lt 30 ] && echo 1 || echo 0
1
企业案例:
输入或通过命令行传入一个字符或数字,如果传入的数字等于1,就打印1,如果等于2,就打印2;如果不等于1也不等于2,就提示输入错误,然后退出程序。
[root@codis-178 ~]# cat 6_34_1.sh
#!/bin/bash
echo -n "pls input a char:"
read var
[ "$var" == "1" ] &&{
echo 1
exit 0
}
[ "$var" == "2" ] &&{
echo 2
exit 0
}
[ "$var" != "2" -a "$var" != "1" ] &&{
echo error
exit 0
}
[root@codis-178 ~]# sh 6_34_1.sh
pls input a char:1
1
[root@codis-178 ~]# sh 6_34_1.sh
pls input a char:2
2
[root@codis-178 ~]# sh 6_34_1.sh
pls input a char:ad
error
开发Shell脚本
分别实现以脚本传参和read读入的方式比较两个整数的大小。
[root@codis-178 ~]# cat 6_35_1.sh
#!/bin/bash
read -p "pls input two num:" a b
[ -z "$a" ] || [ -z "$b" ] &&{
echo "pls input two num again."
exit 1
}
expr $a + 10 &>/dev/null
RETVAR1=$?
expr $b + 10 &>/dev/null
RETVAR2=$?
test $RETVAR1 -eq 0 -a $RETVAR2 -eq 0 ||{
echo "pls input two "num" again."
exit 2
}
[ $a -lt $b ] &&{
echo "$a < $b"
exit 0
}
[ $a -eq $b ] &&{
echo "$a = $b"
exit 0
}
[ $a -gt $b ] &&{
echo "$a > $b"
exit 0
}
[root@codis-178 ~]# sh 6_35_1.sh
pls input two num:6 2
6 > 2
[root@codis-178 ~]# sh 6_35_1.sh
pls input two num:5 6
5 < 6
[root@codis-178 ~]# sh 6_35_1.sh
pls input two num:
pls input two num again.
[root@codis-178 ~]# sh 6_35_1.sh
pls input two num:ddf qr
pls input two num again.
[root@codis-178 ~]# cat 6_35_2.sh
#!/bin/bash
a=$1
b=$2
[ $# -ne 2 ] &&{
echo "USAGE:$0 NUM1 NUM2"
exit 1
}
expr $a + 10 &>/dev/null
RETVAR1=$?
expr $b + 10 &>/dev/null
RETVAR2=$?
test $RETVAR1 -eq 0 -a $RETVAR2 -eq 0 ||{
echo "pls input two "num" again."
exit 2
}
[ $a -lt $b ] &&{
echo "$a < $b"
exit 0
}
[ $a -eq $b ] &&{
echo "$a = $b"
exit 0
}
[ $a -gt $b ] &&{
echo "$a > $b"
exit 0
}
[root@codis-178 ~]# sh 6_35_2.sh
USAGE:6_35_2.sh NUM1 NUM2
[root@codis-178 ~]# sh 6_35_2.sh 6 2
6 > 2
[root@codis-178 ~]# sh 6_35_2.sh 6 6
6 = 6
[root@codis-178 ~]# sh 6_35_2.sh 2 6
2 < 6
[root@codis-178 ~]# sh 6_35_2.sh ol pl
pls input two num again.
打印选择菜单
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
要求:
- 用户输入1时,输出“start installing lamp”提示,然后执行脚本lamp.sh,输出“lamp installed”,并退出脚本
- 用户输入2时,输出“start installing lnmp”提示,然后执行脚本lnmp.sh,输出“lnmp installed”,并退出脚本
- 当输入3时,退出当前脚本
- 当输入任何其他字符时,提示“input error”
[root@codis-178 scripts]# cat 6_36_2.sh
#!/bin/bash
#menu
cat <<END
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
END
read num
expr $num + 1 &>/dev/null
[ $? -ne 0 ] &&{
echo "the num you input must be (1|2|3)"
exit 1
}
[ $num -eq 1 ] &&{
echo "start installing lamp."
sleep 2;
[ -x "/server/scripts/lamp.sh" ] ||{
echo "/server/scripts/lamp.sh does not exist or can not be exec."
exit 1
}
sh /server/scripts/lamp.sh
exit $?
}
[ $num -eq 2 ] &&{
echo "start installing LNMP."
sleep 2;
[ -x "/server/scripts/lnmp.sh" ] ||{
echo "/server/scripts/lnmp.sh does not exist or can not be exec."
exit 1
}
sh /server/scripts/lnmp.sh
exit $?
}
[ $num -eq 3 ] &&{
echo bye.
exit 3
}
[[ $num =~ [1-3] ]] &&{
echo "the num you input must be (1|2|3)"
echo "Input ERROR"
exit 4
}
[root@codis-178 scripts]# sh 6_36_2.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
1
start installing lamp.
lamp is installed.
[root@codis-178 scripts]# sh 6_36_2.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
2
start installing LNMP.
lnmp is installed.
[root@codis-178 scripts]# sh 6_36_2.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
3
bye.
[root@codis-178 scripts]# sh 6_36_2.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
5
[root@codis-178 scripts]# sh 6_36_2.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
adsf
the num you input must be (1|2|3)