Shell脚本快速入门(2)

2020年2月11日 · 774 字 · 4 分钟

今天我们来学习Shell的运算符和流程控制。

运算符

Shell和其他编程语言一样支持多种运算符,包括:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 字符串运算符
  • 文件测试运算符

下面我们一起来看看。

算术运算符

原生bash不支持简单的数学运算,需要借助expr命令。

例如,输出两个数的和:

sum=`expr 1 + 1`
echo $sum

注意:

操作数和操作符之间必须用空格分开;

表达式必须使用反引号包裹;

操作符说明示例
+加法expr 1 + 1
-减法expr 1 - 1
*乘法expr 1 \* 1 需要转义*号
/除法expr 1 / 1
%取余expr 2 % 2

完整示例如下:

a=1
b=2
# 加法
val=`expr $a + $b`
echo "$a+$b=$val"

# 减法
val=`expr $a - $b`
echo "$a-$b=$val"

# 乘法
val=`expr $a \* $b` # 必须转义
echo "$a*$b=$val"

# 除法
val=`expr $a / $b`
echo "$a/$b=$val"

# 取余
val=`expr $a % $b`
echo "$a%$b=$val"

关系运算符

关系运算符是比较两个操作数的数学大小关系,支持数字和数字字符串(如"1")

运算符说明例子
-eq检测两数是否相等[ $a -eq $b ]
-ne检测两数是否不等[ $a -ne $b ]
-gt检查左边是否大于右边(greater than)[ $a -gt $b ]
-lt检查左边是否小于右边(less than)[ $a -lt $b ]
-ge检查左边是否大于等于右边[ $a -ge $b ]
-le检查左边是否小于等于右边[ $a -le $b ]
==判断两数是否相等[ $a == $b ]
!=判断两数是否不想等[ $a != $b ]

下面是一个if比较的示例,if语法将在本文介绍流程控制的时候进行详细学习。

a=10
b=20

if [ $a -eq $b ]
then
	echo "$a=$b"
else
	echo "$a!=$b"
fi

逻辑运算符

逻辑运算符就是与(AND)、或(OR)、非(NOT)。

运算符说明示例
!逻辑非[ !false]返回true
-o逻辑或[ $a -gt 0 -o $b -gt 0] 当a和b有一个大于0时返回true
-a逻辑与[ $a -gt 0 -a $b -gt 0 ]当a和b都大于0时返回true

下面是结合关系运算符的例子:

a=1
b=2

if [ $a != $b ]
then
	echo "1!=2"
else
	echo "1=2"
fi

if [ $a -gt 0 -o $b -gt 0 ]
then
	echo "a或b大于0"
else
	echo "a和b都不大于0"
fi

if [ $a -gt 0 -a $b -gt 0 ]
then
	echo "a和b都大于0"
else
	echo "a和b不都大于0"
fi

字符串运算符

Shell被常用来处理字符串数据,因此有一些专门适用于字符串的运算符。

运算符说明示例
=检查两个字符串是否相等[ $a = $b ]
!=检查两个字符串是否不想等[ $a != $b ]
-z检查字符串长度是否为0[ -z $a ]
-n检查字符串长度是否不为0[ -n $a ]
$检查字符串是否为空[ $a ]

下面是一些示例:

a="hello"
b="world"

if [ $a = $b ]
then
	echo "$a和$b相同"
else
	echo "$a和$b不同"
fi

if [ -z $a ]
then
	echo "$a长度为0"
else
	echo "$a长度不为0"
fi

if [ -n $a ]
then
	echo "$a长度不为0"
else
	echo "$a长度为0"
fi

if [ $a ]
then
	echo "$a不为空"
else
	echo "$a为空"
fi

文件测试运算符

文件测试运算符用于检测文件的各种状态。下表列出了常用的文件测试运算符。

操作符说明示例
-d file检查文件是否是目录[ -d $file ]
-f file检查文件是否是普通文件(不是目录,也不是块设备文件)[ -f $file]
-r file检查文件是否可读[ -r $file ]
-w file检查文件是否可写[ -w $file ]
-x file检查文件是否可执行[ -x $file ]
-s file检查文件大小是否为0[ -s $file ]
-e file检查文件或文件夹是否存在[ -e $file ]
-S检查文件是否是Socket文件[ -S $file ]
-L检查文件是否存在且是一个符号链接[ -L $file ]

下面是一些示例:

file="/etc/passwd"

if [ -d $file ]
then
	echo "$file是目录"
else
	echo "$file不是目录"
fi

if [ -f $file ]
then
	echo "$file是普通文件"
else
	echo "$file不是普通文件"
fi

if [ -e $file ]
then
	echo "$file存在"
else
	echo "$file不存在"
fi

流程控制

Shell的流程控制也包含判断和循环,我们一起来学习一下。

if/else

语法

if condition
then
	 语句1
	 语句2
	 ...
	 语句N
elif condition2
then
	 语句1
	 语句2
	 ...
	 语句N
else
	 语句1
	 语句2
	 ...
	 语句N
fi
  • elif和else分支是可以省略的

  • if/fi 需要配对

下面是一些示例:

a=1
b=2
if [ $a == $b ]
then
   echo "a = b"
elif [ $a -gt $b ]
then
   echo "a > b"
elif [ $a -lt $b ]
then
   echo "a < b"
else
   echo "所有条件都不匹配"
fi

for循环

语法如下

for item in item1 item2 ... itemN
do
	语句1
	语句2
	...
	语句N
done
  • do/done需要配对
  • in列表支持文件列表、字符串、数字和其他数组数据

下面是循环输出/etc下文件和目录的示例:

for dir in `ls /etc`
do
	echo "$dir"
done

while

语法如下

while condition
do
	语句1
	语句2
	...
	语句N
done

下面是一个示例

c=1
while(( $c<=10 ))
do
    echo $c
		c=`expr $c + 1`
done

switch

语法如下

case 值 in
模式1)
	语句1
	语句2
	...
	语句N
	;;
模式2)
	语句1
	语句2
	...
	语句N
	;;
*)
	语句1
	语句2
	...
	语句N
	;;
easc
  • 模式匹配之后不会再执行其他模式语句(不需要手动break)
  • case/easc 必须配对
  • 每个模式语句的末尾必须添加两个分号
  • 使用*号捕获其他模式

如下是一个示例

echo '输入星期几'
read day
case $day in
	1)
		echo "星期一"
		;;
	2)
		echo "星期二"
		;;
	...
	*)
		echo "输入的数字无效"
		;;
  • read是从标准输入读取一行赋值给指定变量

break

break命令允许跳出循环体。下面是一个示例

sum=0

while read n
do
	if [ $n -gt 0 ]
	then
		sum=`expr $sum + $n`
	else
		break
	fi
done

continue

continue命令允许跳过本次循环,直接进行下一轮循环。下面是一个示例

sum=0

while read n
do
	if [ $n -gt 0 ]
	then
		sum=`expr $sum + $n`
	else
		continue # 本次输入不合法,跳过,
	fi
done

九九乘法表

结合今日所学,我们用Shell来打印一个九九乘法表:

#!/bin/bash

i=1

while [ $i -le 9 ] # i <= 9
do
	j=1
	while [ $j -le 9 ] # j <= 9
	do
		if [ $i -ge $j ] # if($i >= $j)
		then
			val=`expr $i \* $j`
			echo -n "$j*$i=$val "
		fi
		j=`expr $j + 1` # j++
	done
	echo
	i=`expr $i + 1` # i++
done

执行结果如下:

1*1=1 
1*2=2 2*2=4 
1*3=3 2*3=6 3*3=9 
1*4=4 2*4=8 3*4=12 4*4=16 
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 

今天的内容是Shell中比较重要的,也是最常用的语法。下一篇将对Shell的输入输出进行学习。

0.jpeg

(未完待续)