shell表达式以及运算符

在Linux系统中,命令执行完成后会返回一个退出状态,如果为0表示退出成功,如何不为0,表示未成功。

退出状态及其含义如下:

退出状态含义
0表示命令执行成功,没有问题
1~125执行失败,脚本命令、系统命令或参数传递错误
126存在该命令,但是无法执行
127未找到该命令
>128命令被系统强制结束

例如:分别使用cat命令以及cdt(不存在),作为测试,如图:

测试命令:

测试命令用于测试表达式真假,如果为真,则返回0,如果为假,则返回非0数值,测试命令有两种格式:

  1. test expression
  2. [ expression ]

上面两种格式的使用效果相同,但是一般使用第二种方式,第二种方式一般配置if、case、while等语句一起使用,shell脚本中的if [ ]中if后面的即为测试命令

注意:[ expressiom ]中的expression和中括号之间前后存在空格

整数比较运算符:

整数比较运算符用于整数比较,不能用于比较字符串以及文件,如果比较结果满足提交,则结果为真(测试条件用0表示),如果不满足则为假。

整数比较运算符

运算符含义
a -eq b如果a等于b,测试结果为0
a -ge b如果a大于等于b,测试结果为0
a -gt b如果a大于b,测试结果为0
a -le b如果a小于等于b,测试结果为0
a -lt b如果a小于b,测试结果为0
a -ne b如果a不等于b,测试结果为0

例如:比较两个数值的大小,注意在引用的时候使用双引号,如图:

也可以将测试命令与输出命令放在一起书写,中间通过&&连接,表示前面的执行成功才会执行后面命令,如图:

整数比较运算符不适用浮点数的比较,如图:

字符串运算符:

字符串运算符用来测试字符串是否为空,两个字符串是否相等或者不相等。

字符串运算符及其含义

字符串运算符含义
string测试字符串string是否不为空
==只是用来判断相等
-n string测试字符串string是否不为空
-z string测试字符串string是否为空
string1 = string2字符串string1是否与string2相同, = 除了可用于判断变量是否相等外,还可以表示赋值
string1 != string2 测试字符串string1是否与字符串string2不相同

字符串比较的时候,建议使用双引号,即使变量为空,也要使用双引号。

下面比较字符串是否相等,设置两个字符串变量var1和var2,如图:

编写程序的时候,要注意空格问题,空格会造成测试结果不相等,如图:

shell编程是严格区分大小写的,hello不等于Hello,如图所示:

字符串赋值和整数赋值没有区别,在进行整数比较的时候,不要使用字符串比较运算符,使用的运算符不同,结果不同,如图:

判断字符串是否相等,前面判断成功才会执行后面,如图:

使用-n和-z来判断字符串是否为空的时候,需要加双引号,否则无法准确判断

例如:下面例子中,没有定义任何变量,直接通过-n和-z判断可以发现都是成功的,如图:

下面的是加了双引号之后可以看到能够准确判断,如图:

如果使用了[[]],那么就不用再使用双引号,如图:

文件操作符:

shell提供了大量的文件操作符,这样可以完成文件的各种测试工作,常用格式如下:

  1. test 文件操作符 文件
  2. [ 文件操作符 文件 ]

常用文件操作符以及含义如下:

文件操作符含义
-d file测试文件是否为目录
-e file测试文件是否存在
-f file测试文件是否为普通文件
-r file测试文件是否是进程可读文件
-s file测试文件长度是否不为0
-w file测试文件是否是进程可写文件
-x file测试文件是否是进程可执行文件
-L file测试文件是否是符号链接文件

例如,测试文件夹abc以及文件aa.txt是否存在,如图:

下面测试一下文件的权限情况,如图:

逻辑运算符:

逻辑运算符用于测试多个条件是否为真或者假

逻辑运算符及其含义如下:

逻辑运算符含义
! expression如果expression为真,测试结果为假
expression1 -a expression2如果expression1和2同时为真,那么结果为真
expression1 -o expression2 如果expression1和2有一个为真,结果为真

逻辑运算符真假表

expr1exp2!exp1!exp2expr1 -a expr2expr1 -o expr2

逻辑判断符

判断符描述
&& 逻辑和,在[[]]和(())表达式中或判断表达式是否为真时使用
|| 逻辑或,在[[]]和(())表达式中 或判断表达式是否为真时使用

判断:

所谓判断就是对语句中的不同条件进行测试,从而执行不同的命令,例如if/else语句,如图:

上图中判断10是否小于12,如果成立,打印小于12,否则大于12,图中的中括号后如果直接加then,此时需要在中括号和then之间加分号;如果不加可以将then写在下面,如图:

exit命令一般伴随着命令结束,表示一个退出状态,如图:

上述命令中,read表示读取一个键盘输入内容,判断是否为空,如果为空,退出状态1,否则为0

注意:退出状态可以自行指定的,特定的值都有特定的用途,不要乱用

上图中,用变量$1表示用户输入的字符串,此字符串表示一个文件,然后进行判断文件是否存在,如果文件不存在,退出状态1,否则存在。

if/else也经常使用嵌套循环,如图:

上图中-z表示测试字符串是否为空,!表示非空,如果非空,那么打印不是空,再次进行判断文件是否存在,如果存在打印存在,反之不存在。

接下来看一组if/elif/else的例子,如图:

注意,在上图中,fi只需要在结尾出现一次就可以啦,其余地方不用

case结构

case命令常用于多分支语句,常根据表达式的值来选择要执行的语句

上图中变量$1表示传入的参数,在执行脚本的时候加入参数,如果匹配1那么打印值为1,以此类推,如果都不匹配,则打印*配置的内容,值未知,注意最后要以esac结尾。

下图中表示根据输入不同参数,输出不同内容,如图:

下面例子表示使用case结构配合for循环来实现清理elk索引以及数据,如下:

#!/bin/bash
: '
 @function: clean elk log
 @author: gongguan
 @date: 2022-04-01
 @说明: 本例子中只写出了2022年的,后续可以继续扩展到2023、2024年等,清理时候根据提示输入年份
 和月份即可
'
cleanLog(){
  for i in $(curl 'localhost:9200/_cat/indices?v' | awk '{print $3}')
  do
    result=$(echo $i | grep ''${month}'')
    if [ -n "${result}" ];then
      curl -XDELETE http://localhost:9200/${result}
    fi

  done
}
read -p "请输入要清楚的年份(2022/2023):" year
case $year in
2022)
  read -p "请输入要清除的月份(01/02/03....):" month
  case $month in
  01)
   cleanLog
   ;;
  02)
   cleanLog
   ;;
   03)
   cleanLog
   ;;
   04)
   cleanLog
   ;;
   05)
   cleanLog
   ;;
    06)
   cleanLog
   ;;
   07)
   cleanLog
   ;;
   08)
   cleanLog
   ;;
   09)
   cleanLog
   ;;
   10)
   cleanLog
   ;;
   01)
   cleanLog
   ;;
   12)
   cleanLog
   ;;
   *)
    echo "输入的月份不匹配"  
  esac
;;
*)
  echo "年份不匹配,请重新输入....."
;;
esac

算术运算符

运算符举例结果
+(加运算)3+58
-(减运算)5-32
*(乘运算)5*315
/(除运算)8/24
%(取余)8%32
**(幂运算)5**3125

1、在进行整数运算的时候,最终结果将是商的整数部分,忽略四舍五入,忽略小数部分,如图:

上图中,9除2等于4,8除以5等于1。

2、接下来看下取余数以及幂运算的例子,如图:

注意:在除法以及取余的过程中,除数不能为0,否则会报错。

运算表达式:

表达式 示例
$(()) $(())
$[] $[1+1]

除了使用let,还可以通过$[]或者$(())

3、下面脚本例子通过$[] 来进行加法运算,循环执行10次,如图:

执行结果如下:

4、下面脚本例子通过$(()) 来进行加法运算,循环执行10次,如图:

结果如下:

注意:$[] 和$(()) 等效,提供同样的功能, 但是都不支持浮点运算

$(())表达式还有一个用途,三目运算

5、下面例子,如果条件为真输出1,否则输出0,如图:

6、下面例子,如果条件为真,输出冒号前面的数字,否则输出后面的数字,如图:

注意:返回值不支持字符串

其他运算工具(let/expr/bc)

除了 Shell 本身的算数运算表达式,还有几个命令支持复杂的算数运算:

命令 描述
let 赋值并运算,支持++、–
expr 乘法*需要加反斜杠转义\*
bc 计算器,支持浮点运算、 平方等
#let命令的例子如下:
let VAR=(1+2)*3 ; echo $VAR
x=10 ; y=5
let x++;echo $x 每执行一次 x 加 1
let y--;echo $y 每执行一次 y 减 1
let x+=2 每执行一次 x 加 2
let x-=2 每执行一次 x 减 2

#expr命令示例如下:
expr 1 \* 2 运算符两边必须有空格
expr \( 1 + 2 \) \* 2 使用双括号时要转义

#bc命令示例如下:
bc 本身就是一个计算器,可直接输入命令,进入解释器。
echo 1 + 2 |bc 将管道符前面标准输出作为 bc 的标准输入
echo "1.2+2" |bc
echo "10^10" |bc
echo 'scale=2;10/3' |bc 用 scale 保留两位小数点

由于 Shell 不支持浮点数比较,可以借助 bc 来完成需求:

上图中运算如果为真返回 1,否则返回 0

7、下面例子表示通过bc计算除法,并保留两位小数,如图:

算术复合运算符

运算符举例等价表达式
+=a+=5a=a+5
-=a-=5a=a-5
*=a*=5a=a*5
/=a/=3a=a/3
%=a%=5a=a%5

Shell 括号用途总结:

命令用途
()用途 1:在运算中,先计算小括号里面的内容
用途 2:数组
用途 3:匹配分组
(()) 用途 1:表达式,不支持-eq 这类的运算符。不支持-a 和-o,支持<=、>=、<、>这类
比较符和&&、||
用途 2:C 语言风格的 for(())表达式
$() 执行 Shell 命令,与反引号等效
$(())用途 1:简单算数运算
用途 2:支持三目运算符 $(( 表达式?数字:数字 ))
[] 条件表达式,里面不支持逻辑判断符 &&、||,支持-a、-o
[[]] 条件表达式,里面不支持-a 和-o,不支持<=和>=比较符,支持-eq、<、>这类比较
符。支持=~模式匹配,也可以不用双引号也不会影响原意,比[]更加通用
$[] 简单算数运算
{}对逗号(,)和点点(…)起作用,比如 touch {1,2}创建 1 和 2 文件,touch {1..3}创建 1、2 和 3 文件
${} 用途 1:引用变量
用途 2:字符串处理

标签