天天看点

shell中的条件判断与控制流程条件判断

条件判断

1.按照文件类型进行判断

测试选项 作用
-b 文件 判断该文件是否存在,并且是否为块设备文件(是块设备文件则为真)
-c 文件 判断文件是否存在,并且是否为字符设备文件(是字符设备文件为真)
-d 文件 判断文件是否存在,并且是否为目录文件(是目录则为真)
-e 文件 判断文件是否存在(存在为真)
-f 文件 判断文件是否存在,并且是否为普通文件(是普通文件则为真)
-L 文件 判断文件是否存在,并且是否为符号链接文件(是符号链接文件为真)
-p 文件 判断文件是否存在,并且是否为管道文件(是管道文件则为真)
-s 文件 判断文件是否存在,并且是否为空(非空为真)
-S 文件 判断文件是否存在,且是否为套接字文件(是套接字文件为真)

判断式有两种格式(通常使用后一种):

test -e /etc/profile

[ -e /etc/profile ](中括号和条件判断式之间一定要有空格!)

例如,执行:

[ -e /etc/profile ] && echo yes || echo no

执行结果为 yes

2.按文件权限判断

测试选项 作用
-r 文件 文件存在且拥有读权限为真
-w 文件 文件存在且有写权限为真
-x 文件 文件存在且拥有执行权限为真
-u 文件 文件存在且拥有SUID权限为真
-g 文件 文件存在且拥有SGID权限为真
-k 文件 文件存在且拥有SBIT权限为真

例如执行:

[ -w /etc/profile ] && echo yes || echo no结果为yes

这里要注意:权限测试并不区分是哪一个用户的权限,只要存在一个用户有相应的权限即为真。

3.比较两个文件

测试选项 作用
文件1 -nt文件2 判断文件1的修改时间是否比文件2新(新,则为真)
文件1 -ot文件2 判断文件1的修改时间是否比文件2旧(旧,则为真)
文件1 -ef文件2 判断文件1是否和文件2的lnode号一致,可以理解为判断两个文件是否为同一个文件。这个判断可用于判断硬链接。

例如,执行:

ln /home/hunan/student.txt /home/hunan/bin/stu.txt

[ /home/hunan/student.txt -ef /home/hunan/bin/stu.txt ] && echoyes || echo no

上述命令先是创建了一个硬链接,然后判断指向的文件是否相同,结果为:yes

4.比较两个整数

测试选项 作用
整数1 -eq整数2 整数1等于整数2为真
整数1 -ne整数2 整数1不等于整数2为真
整数1 -gt整数2 整数1大于整数2为真
整数1 -lt整数2 整数1小于整数2为真
整数1 -ge整数2 整数1大于等于整数2为真
整数1 -le整数2 整数1小于等于整数2为真

例如,执行:

$[ 23 -gt 22 ] && echo yes || echo no

yes

$[ 23 -lt 22 ] && echo yes || echo no

no

5.比较两个字符串

测试选项 作用
-z 字符串 字符串为空返回真
-n 字符串 字符串非空返回真
字符串1==字符串2 字符串1和字符串2相等返回真
字符串1!=字符串2 字符串1和字符串2不相等返回真

例如,执行:

$name=mike

$[ -z $name ] && echo yes || echo no

no

$[ $name == mike ] && echo yes || echo no

yes

6.shell中的与,或,非

测试选项 作用
判断式1 -a判断式2 逻辑与
判断式1 -o判断式2 逻辑或
! 判断式 逻辑非

例如,执行:

$aa=11

$[ -n $aa -a "$aa" -gt 22 ] && echo yes || echo no

no

控制流程

1.单分支if条件语句

if [ 条件判断式 ];then
    程序
fi
           

或者

if [ 条件判断式 ]
    then
        程序
fi
           

注意:

1.要记得以fi结尾/2.条件判断式和中括号之间必须有空格/3.如果then和if在同一行要以 ; 分隔。

示例1:判断当前用户是否为root用户。思路:用env输出所有环境变量,用grep提取出USER变量,用cut将USER=XXX以“=”为分隔符切分,取切分后的第二个字符串即为当前用户名。命令之间以管道连接。

脚本内容:

#!/bin/bash
#提取出用户名赋值给test变量
test=$(env| grep USER | cut -d "=" -f 2)
if [ $test == "root" ];then
<span style="white-space:pre">	</span>echo "this is root login."
fi
           

注意:要给脚本执行权限才能执行( chmoda+x *.sh )。

示例2:判断分区使用率。当根分区使用率大于某一阈值,给出警告。思路:

df -h | grep sda4 | awk '{print $5}'| cut -d "%" -f 1

df -h打印分区信息,我这里的根分区挂在在sda4,用grep过滤出这一行,用awk打印出第五部分,在用cut切掉%号。即可得到使用率数值。

脚本内容:

#!/bin/bash
#提取出当前根分区的使用率
test=$(df -h | grep sda4 | awk '{print $5}' | cut -d "%" -f 1)
if [ "$test" -gt 30 ];then
    echo "/ is full!"
fi
           

(这里为了体现程序作用,阈值取 30%. )

2.双分支if语句

if[条件判断式 ]
    then
        条件成立时执行语句
    else
        条件不成立时执行语句
fi
           

示例3:用户输入一个路径,程序判断是否为一个目录。思路:用read命令读取用户输入,用-d判断是否为目录。

脚本内容:

#!/bin/bash
read -t 30 -p "请输入路径:" path
if [ -d $path ];then
    echo "is directory!"
else
    echo "not directory!"
fi
           

示例4:判断apache服务是否启动。思路:用psaux列出所有进程,过滤出含有httpd但是不含grep的进程(因为grephttpd命令也会产生一个含有httpd的进程)

脚本内容:

#!/bin/bash
test=$(ps aux | grep httpd | grep -v grep)
#如果字符串不为空
if [ -n $test ]
	then
		echo “$(date) httpd is ok” >> /tmp/autostart-acc.log
	else
		echo “$(date) restart httpd !!” >> /tmp/autostart-err.log
		/etc/rc.d/init.d/httpd start
fi
           

注意:这种方法,脚本名中不能含有httpd!

3.多分支if语句

if [ 条件判断式1 ]
	then
		当条件判断式1成立,执行语句
elif [ 条件判断式2 ]
	then
		当条件判断式2成立,执行语句
             . . . 省略 . . .
else
	当所有条件判断式都不成立,执行语句
fi
           

示例 5 :判断输入的文件类型

脚本内容:

#!/bin/bash
#读入用户输入的路径
read -t 30 -p 请输入路径名: path
if [ -z $path ]
	then
		echo 请输入路径。
		exit 1
elif [ ! -e $path ]
	then
		echo 您输入的路径不存在!
		exit 2
elif [ -f $path ]
	then
		echo 您输入的是普通文件。
elif [ -d $path ]
	then
		echo 您输入的是目录。
else
	echo 您输入的是其它文件。
fi
           

4. 多分支 case 语句

case $变量名 in
	“值1”)
		如果变量的值等于值1,则执行程序1
		;;
	“值2”)
		如果变量的值等于值2,则执行程序2
		;;
	. . . 省略其它分支 . . .
	*)
		如果变量的值都不是以上的值,则执行此程序
	;;
esac
           

注意:每次选择之后都要加上“双分号”!除了最后的 * 其它的值都要被双引号引起来。

示例6:根据用户输入做出不同反应。

#!/bin/bash
  read -t 30 -p '请输入你的选择 yes/no:' cho
  case $cho in
           "yes")
                   echo 你的选择是yes
                   ;;
           "no")
                   echo 你的选择是no
                   ;;
          *)
                  echo 你的选择是其它。
                  ;;
  esac
           

5.for循环

语法1:

for  变量 in 值1 值2 值3...
	do
		程序
	done
           

示例 7 :循环打印数字

#!/bin/bash
for i in 1 2 3 4 5
	do
		echo $i
	done
           

示例 8 :批量解压缩

#!/bin/bash
cd /root/test
for i in $(ls *.tar.gz *.gz)
	do
		tar -zxf $i
	done
           

语法 2 :

for ((初始值; 循环空值条件; 变量变化))
	do
		程序
	done
           

示例 9 :计算 1+2+...+100

#!/bin/bash
   s=0
   for ((i=1; i<=100; i=i+1))
           do
                   s=$(($s+$i))
           done
   echo $s
           

6.while循环

while [ 条件判断式 ]
	do
		程序
	done
           

示例10:用while循环计算1+2+...+100

#!/bin/bash
   s=0
   i=1
   while [ $i -le 100 ]
           do
                   s=$(($i+$s))
                   i=$(($i+1))
           done
   echo "the sum is:"$s
           

7.until 循环

until循环和while循环相反,until循环时只要条件判断式不成立则继续循环,一旦条件判断式成立则停止循环。

until [ 条件判断式 ]
	do
		程序
	done
           

示例11:用until循环计算1+2+...+100

#!/bin/bash
   s=0
   i=1
   until [ $i -gt 100 ]
           do
                   s=$(($s+$i))
                   i=$(($i+1))
           done
   echo 'the sum is:'$s