shell选择结构(if)
Posted 何翰宇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell选择结构(if)相关的知识,希望对你有一定的参考价值。
文章目录
一、条件判断
1. 语法格式
- 格式1:
test
条件表达式 - 格式2:[ 条件表达式 ]
- 格式3:[[ 条件表达式 ]](支持在正则表达式)
test的参数很多,可以用man
命令查看
2. 条件判断相关参数
1)判断文件存在与否
-e 是否存在 不管是文件还是目录,只要存在,条件就成立
-f 是否为普通文件
-d 是否为目录
-S socket
-p pipe
-c character
-b block
-L 软link
三种语法格式:
test -e file1 只要文件存在条件为真
[ -d ~/tmp/files ] 判断目录是否存在,存在条件为真
[ ! -d ~/tmp/files ] 判断目录是否存在,不存在条件为真
[[ -f ~/tmp/file1 ]] 判断文件是否存在,并且是一个普通的文件
-s 判断文件是否有内容(大小),非空文件条件满足
说明:-s表示非空,! -s 表示空文件
说明:file1中是有内容的
[root@lamp tmp]# test -s file1
[root@lamp tmp]# echo $?
0
[root@lamp tmp]# touch temp
[root@lamp tmp]# cat temp
[root@lamp tmp]# test -s temp;echo $?
1
[root@lamp tmp]# test ! -s temp;echo $?
0
[root@lamp tmp]# echo $?
0
[root@lamp tmp]# test ! -s file1;echo $?
1
2)文件权限相关的判断
-r 当前用户对其是否可读
-w 当前用户对其是否可写
-x 当前用户对其是否可执行
-u 是否有suid
-g 是否sgid
-k 是否有t位
3)两个文件的比较判断
file1 -nt file2 比较file1是否比file2新
file1 -ot file2 比较file1是否比file2旧
file1 -ef file2 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
test file1 -nt file2
[ file1 -ot file2 ]
[root@lamp tmp]# ll
total 4
-rw-r--r-- 1 root root 12 Aug 3 19:10 file1
-rw-r--r-- 1 root root 0 Aug 3 19:17 file2
drwxr-xr-x 2 root root 6 Aug 3 18:51 files
-rw-r--r-- 1 root root 0 Aug 3 19:13 temp
[root@lamp tmp]# test file1 -nt file2;echo $? # 比较file1是否比file2新
1
[root@lamp tmp]# test file1 -ot file2;echo $? # 比较file1是否比file2旧
0
[root@lamp tmp]# [ file1 -ef feil2 ];echo $? # 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode
1
4)整数之间的判断
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
5)字符串之间的判断
-z 是否为空字符串 字符串长度为0,就成立
-n 是否为非空字符串 只要字符串非空,就是成立
string1 = string2 是否相等
string1 != string2 不等
[root@lamp tmp]# str1=abc
[root@lamp tmp]# str2=qwer
[root@lamp tmp]# test -z $str1
[root@lamp tmp]# echo $?
1
[root@lamp tmp]# test -n $str1
[root@lamp tmp]# echo $?
0
[root@lamp tmp]# [ $str1 = $str2 ]
[root@lamp tmp]# echo $?
1
[root@lamp tmp]# [ $str1 != $str2 ];echo $?
0
6)多重条件判断
逻辑判断符号:
-a
和&&
(and
逻辑与) 两个条件同时满足,整个大条件为真-o
和||
(or
逻辑或) 两个条件满足任意一个,整个大条件为真
[ 1 -eq 1 -a 1 -ne 0 ] 整个表达式为真
[ 1 -eq 1 ] && [ 1 -ne 0 ]
[ 1 -eq 1 -o 1 -ne 1 ] 整个表达式为真
[ 1 -eq 1 ] || [ 1 -ne 1 ]
[root@lamp tmp]# [ 1 -eq 0 ] && echo true || echo false
false
[root@lamp tmp]# [ 1 -eq 1 ] && echo true || echo false
true
&&:前面的表达式为真
||:前面的表达式为假
总结:
1、; && ||都可以用来分割命令或者表达式
2、; 完全不考虑前面的语句是否正确执行,都会执行;号后面的内容
3、&& 需要考虑&&前面的语句的正确性,前面语句正确执行才会执行&&后的内容;反之亦然
make && make install
4、|| 需要考虑||前面的语句的非正确性,前面语句执行错误才会执行||后的内容;反之亦然
5、如果&&和||一起出现,从左往右依次看,按照以上原则
一、流程控制语句
1. 基本语法结构
if
if [ 条件 ];then
要执行的命令1
要执行的命令...
fi
if+else
if [ 条件 ];then
要执行的命令
else
要执行的命令
fi
if+elif+else
if [ 条件1 ];then
要执行的命令1
elif [ 条件2 ];then
要执行的命令2
else
要执行的命令3
fi
#如果条件1满足,执行命令1后结束;
#如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;
#如果条件1和条件2都不满足执行命令3结束.
嵌套if+else
if [ 条件1 ];then
要执行的命令
if [ 条件2 ];then
要执行的命令
fi
else
if [ 条件3 ];then
要执行的命令
elif [ 条件4 ];then
要执行的命令
else
要执行的命令
fi
fi
#如果条件1满足,执行命令1;如果条件2也满足执行命令2,如果不满足就只执行命令1结束;
#如果条件1不满足,不看条件2;直接看条件3,如果条件3满足执行命令3;
#如果不满足则看条件4,如果条件4满足执行命令4;否则执行命令5
3. 示例
# 通过uid判断是否是root账号
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin"
the user is admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is not admin"
the user is not admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
the user is admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin"
the user is admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is not admin"
the user is not admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
the user is admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin"
the user is admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is not admin"
the user is not admin
[root@lamp tmp]# [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
the user is admin
1)类C风格的数值比较
类似于C语言的比较方法
注意:在(( ))中,=表示赋值;==表示判断
[test@lamp tmp]$ ((1==2));echo $?
1
[test@lamp tmp]$ ((1<2));echo $?
0
[test@lamp tmp]$ ((1>=1));echo $?
0
[test@lamp tmp]$ ((`id -u`==0));echo $?
1
[test@lamp tmp]$ unset $a
[test@lamp tmp]$ ((a=123));echo $a
123
[test@lamp tmp]$ unset a
[test@lamp tmp]$ ((a==123));echo $?
1
2)字符串比较
注意:双引号引起来,看作一个整体;= 和 == 在 [ 字符串 ] 比较中都表示判断
[root@lamp tmp]# str="hello world";tmp="world"
[root@lamp tmp]# [ $str = $tmp ];echo $?
-bash: [: too many arguments
2
[root@lamp tmp]# [ "$str" = "$tmp" ];echo $?
1
[root@lamp tmp]# [ "$str" != "$tmp" ];echo $?
0
[root@lamp tmp]# [ "$str" !== "$tmp" ];echo $?
-bash: [: !==: binary operator expected
2
[root@lamp tmp]# [ "$str" == "$tmp" ];echo $?
1
[root@lamp tmp]# test "$str" != "$tmp";echo $?
0
2. 使用案例
1)判断当前主机是否和远程主机是否能ping通
- 使用哪个命令实现 ping -c
- 根据命令的执行结果状态来判断是否通 $?
- 根据逻辑和语法结构来编写脚本(条件判断或者流程控制)
#!/bin/bash
# Name:ping.sh
# Path:/test_shell/
#获取远程主机的IP地址(定义变量让用户自己输入)
read -p "请输入你要ping的远程主机ip:" ip
#使用ping命令来判断是否和远程主机互通
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "当前主机和远程主机$ip是互通的"
else
echo "当前主机和远程主机$ip是不通的"
fi
或者
#!/bin/bash
# Name:ping.sh
# Path:/test_shell/
#获取远程主机的IP地址(定义变量让用户自己输入)
read -p "请输入你要ping的远程主机ip:" ip
#使用ping命令来判断是否和远程主机互通
ping -c1 $ip &>/dev/null
[ $? -eq 0 ] && echo "当前主机和远程主机$1是互通的" || echo "当前主机和远程主机$1是不通的
测试
[root@lamp test_shell]# ./ping.sh
请输入你要ping的远程主机ip:www.baidu.com
当前主机和远程主机是互通的
[root@lamp test_shell]# ./ping.sh
请输入你要ping的远程主机ip:192.168.44.25
当前主机和远程主机是不通的
2)判断一个进程是否存在
思路:
1.查看进程的相关命令ps -ef
2.根据命令的返回状态值来判断进程是否存在 $?
3.根据逻辑用脚本语言实现
#!/bin/bash
# Name:process.sh
# Path:/test_shell
# Usage:/test_shell/process.sh
# Describe:判断一个进程是否存在
#定义变量
read -p "请输入要判断的进程名:" process
#通过命令查看进程是否存在
pgrep $process &>/dev/null
#通过命令执行的状态判断是否存在
if [ $? -eq 0 ];then
echo "进程$process存在"
else
echo "进程$process不存在"
fi
pgrep命令:以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
选项
-o:仅显示找到的最小(起始)进程号;
-n:仅显示找到的最大(结束)进程号;
-l:显示进程名称;
-P:指定父进程号;pgrep -p 4764 查看父进程下的子进程id
-g:指定进程组;
-t:指定开启进程的终端;
-u:指定进程的有效用户ID。
```shell
## 或者
[ $? -eq 0 ] && echo "进程$process存在" || echo "进程$process不存在"
测试
[root@lamp test_shell]# chmod +x process.sh
[root@lamp test_shell]# ./process.sh
请输入要判断的进程名:httpd
进程httpd存在
[root@lamp test_shell]# ./process.sh
请输入要判断的进程名:mysql
进程mysql存在
3)输入一个用户,用脚本判断该用户是否存在
#!/bin/bash
read -p "请输入需要判断的用户名:" user
id $user &>/dev/null
test $? -eq 0 && echo "$user用户存在" || echo "$user用户不存在"
测试
[root@lamp test_shell]# ./test_user.sh
请输入需要判断的用户名:test
test用户存在
[root@lamp test_shell]# ls /home
test
4)判断vsftpd软件包是否安装,如果没有则自动安装(yum源已配好)
#!/bin/bash
rpm -q vsftpd &>/dev/null
if [ $? -eq 0 ];then
echo "vsftpd已经安装"
else
echo "该软件没有安装,正在安装..."
yum install -y vsftpd &> /dev/null
if [ $? -eq 0 ];then
echo "vsftpd安装成功"
else
echo "vsftpd安装失败"
fi
fi
测试
[root@lamp test_shell]# ./auto_yum.sh
该软件没有安装,正在安装...
vsftpd安装成功
以上是关于shell选择结构(if)的主要内容,如果未能解决你的问题,请参考以下文章