在前边的 if 语句中,if 根据后面命令的退出码是否为 0 来决定是否执行 then 后面的语句 块,如果存在 else 语句,在命令退出码非 0 的情况下才会执行 else 后面的语句块。
并且if 后面跟着的都是命令。那么脚本中的 if 语句能不能像其他语言,如 Java 中的 if 语句根 据后面的表达式返回的 true 或 false 来决定是否执行 then 或 else 后面的语句块呢!
但是要注意,在脚本中 if 判断的一定是后面命令的退出码是 0 或非 0,那么解决的方法是什
么呢!就是 test 命令
,test 命令提供了在 if…then 语句中测试不同条件的途径,如果 test
后面的条件成立,那么 test 命令返回的退出码为 0,如果条件不成立,test 命令返回的退
出码为 1,这样既满足了 if 语句根据命令退出码来决定执行方向,同时又拓宽了判断条
件。
-
test 命令一般有两种格式:
-
test 表达式
-
[ 表达式 ]
-
但是需要注意的是如果使用方括号方式时,要注意在表达式** 两边加上空格 **,否则执行会提示错误信息。
-
-
使用第一种方式的语句格式如下。
if test 表达式 then 语句块 fi
-
当 test 命令后面的的表达式成立,test 命令的退出码为 0,如果 test 命令后面的表达式不成立,test 命令的退出码为 1。如下面的例子。
-
例子:判断两个数值类的大小并输出信息
#!/bin/bash # 声明变量并赋值 var1=100 var2=200 # 判断变量 var1 是否大于变量 var2 if test $var1 -gt $var2 then echo "$var1 > $var2" else echo "$var1 < $var2" fi
-
控制台显示:
100 < 200
-
-
-
上面的脚本中使用了 test 命令,后面跟着的是逻辑表达式。还有一种方式可以替代上面的方式,就是使用方括号来替代 test 命令,修改上面的代码如下。
-
例子:使用方括号的方式实现上面的例子,通常这种方式使用较为普遍。
#!/bin/bash var1=100 var2=200 if [ $var1 -gt $var2 ] then echo "$var1 > $var2" else echo "$var1 < $var2" fi
-
注意方括号是 test 命令的简写方式,方括号中是 test 命令的条件,另外需要注意的是方括号的两边要有空格,否则会报错。通常使用的就是这种方式。
-
-
test 命令可以判断三类条件:
- 1、数值比较
- 2、字符串比较
- 3、文件比较
数值比较比较常见,下面的表中列出了数值比较符,这和 Java 中是有区别的。
-
数值比较:
比较符 说明 v1 -eq v2 v1 是否等于 v2 v1 -gt v2 v1 是否大于 v2 v1 -ge v2 v1 是否大于或等于 v2 v1 -lt v2 v1 是否小于 v2 v1 -le v2 v1 是否小于或等于 v2 v1 -ne v2 v1 是否不等于 v2 -
例子:比较大小。通过一个例子说明数值比较。
#!/bin/bash var1=200 var2=300 # 判断 var1 是否等于 var2 if [ $var1 -eq $var2 ] then echo "$var1 等于$var2" # 判断 var1 是否大于 var2 elif [ $var1 -gt $var2 ] then echo "$var1 大于$var2" # 判断 var1 是否小于 var2 elif [ $var1 -lt $var2 ] then echo "$var1 小于$var2" fi
-
控制台输出:
200 小于 300
-
-
例子:比较小数是否可以??浮点数是否可以比较!通过例子说明:
#!/bin/bash var1=3.33 var2=3 if [ $var1 -gt $var2 ] then echo "$var1 大于$var2" else echo "$var1 小于等于$var2" fi
-
控制台输出:
3.33 小于等于 3
比较结果是错误的,注意:脚本中只能处理整数,不支持浮点数作为数值比较。
-
test 命令还支持比较字符串,比较字符串和比较数值使用的比较符是不同的,使用标准的数学比较符进行字符串的比较, 而用文本代码来比较数值,这是要注意的。
-
字符串比较符列表说明:
比较符 说明 s1 = s2 s1 是否于 s2 相同 s1 != s2 s1 是否于 s2 不同 s1 > s2 s1 是否比 s2 大 s1 < s2 s1 是否比 s2 小 -n s1 s1 的长度是否不等于 0,是否非空 -z s1 s1 的长度是否为 0,是否为空 -
例子:当前用户是否是 root(比较字符串是否相同。)
#!/bin/bash # 判断当前登录用户是否是 root if [ $USER = "root" ] then echo "当前用户是超级管理员:$USER" # 判断当前登录用户是否是 yarn elif [ $USER = "hadoop01" ] then echo "当前用户是:$USER" fi
-
控制台显示:
当前用户是:hadoop01
-
判断字符串不相同,使用方式和判断字符串相同相似,可以使用在相同的场合。
-
-
例子:判断用户
#!/bin/bash user=yarn if [ $user != "root" ] then echo "你不是管理员 root" elif [ $user = "root" ] then echo "欢迎管理员$user 登录!" fi
-
控制台显示:
你不是管理员 root
-
-
例子:比较字符串是否相等(字符串比较考虑字符的大小写)
#!/bin/bash if [ "Hello" = "hello" ] then echo "Hello = hello" else echo "Hello != hello" fi
-
控制台显示:
Hello != hello
-
-
例子:字符串大于小于比较时,大于号和小于号要转义,否则结果出错
#!/bin/bash # 注意:系统会将大于号>认为是重定向符,认为 bcd 是文件名 # 会在当前目录创建一个 bcd 文件 if [ "abc" > "bcd" ] then echo "abc > bcd" else echo "abc <= bcd" fi
-
控制台输出:
abc > bcd
-
-
脚本似乎正确执行,事实上系统将大于号视同重定向符,将 bcd 认为是文件名,会在当 前目录创建一个 bcd 文件,并且执行结果也是错的。要注意,字符串比较时的大于号和 小于号要转义,修改上面脚本如下。
-
例子:修改上面的例子
#!/bin/bash # 大于号要转义 if [ "abc" \> "bcd" ] then echo "abc > bcd" else echo "abc <= bcd" fi
-
控制台显示:
abc <= bcd
-
-
-
判断字符串变量是否 非空使用比较符-n,判断字符串是否为空使用比较符-z。在字符串操作中使用较多,下面通过例子说明。
-
例子:字符串非空判断
#!/bin/bash # 声明变量 var1="abcdefg" # 声明一个空串 var2="" var3= # 判断变量非空 if [ -n "$var1" ] then echo "变量 var1 非空:$var1" fi # 判断变量是否为空取反,判断变量是否不为空 if [ ! -z "$var1" ] then echo "变量 var1 非空:$var1" fi # 判断变量是否为空 if [ -z "$var2" ] then echo "变量 var2 为空" fi # 判断变量是否不为空取反,判断变量是否为空 if [ ! -n "$var2" ] then echo "变量 var2 为空" fi # 判断变量是否为空 if [ -z "$var3" ] then echo "变量 var3 为空" fi # 变量 var4 未定义,变量任然为空 if [ -z "$var4" ] then echo "变量 var4 为空" fi
-
控制台输出:
变量 var1 非空:abcdefg 变量 var1 非空:abcdefg 变量 var2 为空 变量 var2 为空 变量 var3 为空 变量 var4 为空
-
-
- 脚本中常用到的是文件比较,test 命令允许测试 Linux 系统上的文件和目录的状态。下面表中是文件比较常用到的测试函数。
测试符 说明 -d filename filename 是否存在并是一个目录 -e filename filename 是否存在 -f filename filename 是否存在并是一个文件 -r filename filename 是否存在并可读 -s filename filename 是否存在并非空 -w filename filename 是否存在并可写 -x filename filename 是否存在并可执行 -O filename filename 是否存在并属于当前用户 -G filename filename 是否存在并且默认组与当前用户相同
这些测试函数可以让你检查文件系统中的文件。在脚本中对要访问的文件进行操作前要做的检查工作,脚本中经常要用到。
-
例子:判断文件是否为目录:-d 检查文件是否在文件系统中以目录的方式存在,当要在此目录下读写文件时经常用到,如果目录本身不存在,要给出提示信息或首先创建目录,下面通过例子说明。
#!/bin/bash # 声明一个目录变量 dir1=/home/hadoop01/bash01 # 判断/home/hadoop01/bash01 是否存在并且是个目录 if [ -d "$dir1" ] then # 切换到/home/hadoop01/bash01 目录下 cd ${dir1} # 创建一个临时目录 tmp mkdir tmp # 切换到 tmp 目录下 cd tmp # 创建一个空日志文件 touch logs.log # 将当天的日期输入到文件中 date > logs.log # 在控制台显示日志文件内容 cat logs.log else # 如果目录不存在,在控制台显示提示信息 echo "$dir1 is not exist!" fi
脚本执行后,如果/home/hadoop01/bash01 目录存在,会在目录下创建一个 tmp 目录,在 tmp目录中创建一个 logs.log 日志文件,如果目录不存在,会在控制台显示提示信息:目录不存在。
-
下面的例子首先判断当前用户是否是 hadoop01,如果不是 hadoop01 用户不允许操作 hadoop01 用户的 工作目录。如果当前用户是 hadoop01,判断/home/hadoop01/bash01/tmp 目录是否存在,如果存在 追加 hadoop01 用户登录信息到日志文件中。如果 tmp 目录不存在,首先创建 tmp 目录并且在 目录中创建日志文件并输入用户登录信息。
#!/bin/bash if [ $USER = "hadoop01" ] then if [ -d "/home/hadoop01/bash01/tmp" ] then cd /home/hadoop01/bash01/tmp dateStr=`date +%D" "%T` echo "$dateStr: User $USER login system" >> logs.log else cd /home/hadoop01/bash01 mkdir tmp cd tmp dateStr=`date +%D" "%T` echo "$dateStr: User $USER login system" > logs.log fi else echo "You is not User hadoop01!" fi
-
日志文件信息格式:
02/29/16 17:40:49: User hadoop01 login system
-
-
例子:使用-e 判断文件是否存在,文件可以是目录和普通文件: -e 判断文件或目录是否存在,判断更宽泛,包括普通文件和目录文件。下面通过例子说明。
#!/bin/bash # 判断/home/hadoop01/bash01 目录是否存在 if [ -e "/home/${USER}/bash01" ] then # 判断 tmp 目录是否存在 if [ -e "/home/${USER}/bash01/tmp" ] then # 判断 tmp 目录下的 logs.log 日志文件是否存在 if [ -e "/home/${USER}/bash01/tmp/logs.log" ] then cd /home/${USER}/bash01/tmp dateStr=`date +%D" "%T` echo "$dateStr: User $USER login system" >> logs.log else cd /home/${USER}/bash01/tmp dateStr=`date +%D" "%T` echo "$dateStr: User $USER login system" > logs.log fi else mkdir /home/${USER}/bash01/tmp dateStr=`date +%D" "%T` echo "$dateStr: User $USER login system" > /home/${USER}/bash01/tmp/logs.log fi else echo "/home/${USER}/bash01 is not exist!" fi
在脚本中首先判断目录是否存在,然后判断目录下的日志文件是否存在,如果文件存在 追加日志信息到日志文件,否则创建一个日志文件。脚本中对 tmp 目录也做了判断,如 果不存在,创建 tmp 目录和 logs.log 文件。
-
-e 判断文件或者目录是否存在,如果具体到目录,可以使用-d。如果具体到文件,可以 使用-f。下面通过例子说明。
#!/bin/bash # 判断目录是否存在,包括 bash01/tmp if [ -d "/home/hadoop01/bash01/tmp" ] then # 判断 logs.log 日志文件是否存在 if [ -f "/home/hadoop01/bash01/tmp/logs.log" ] then cd /home/hadoop01/bash01/tmp dateStr=`date +%D" "%T` # 追加日志信息 echo "$dateStr: User $USER login system" >> logs.log else cd /home/hadoop01/bash01/tmp dateStr=`date +%D" "%T` # 创建日志文件并输入日志信息 echo "$dateStr: User $USER login system" > logs.log fi else # 递归创建目录 mkdir -p /home/hadoop01/bash01/tmp cd /home/hadoop01/bash01/tmp dateStr=`date +%D" "%T` echo "$dateStr: User $USER login system" > logs.log fi
-
-r 用来判断对文件是否有可读权限,如下说明:
--w-rw-r--. 1 hadoop01 hadoop01 35 3 月 1 10:49 file04
-
文件 file04 的属主是 hadoop01,但是 hadoop01 没有读权限只有写权限,如果要查看文件内容会提示警告信息,如下:
$ cat file04 cat: file04: 权限不够
-
-
下面的例子是判断文件是否有读写权限如果有显示文件内容,如果没有读权限,先修改用户权限,然后显示文件内容。
#!/bin/bash # 声明变量 file=/home/hadoop01/bash01/file04 # 判断文件是否可以读 if [ -r "$file" ] then # 显示文件内容 cat $file else # 判断当前用户是否是 hadoop01 if [ "$USER" = "hadoop01" ] then # 给 hadoop01 用户增加读权限 chmod u+r $file cat $file else # 如果不是 hadoop01 用户,提示信息 echo "You are not a hadoop01 user!" fi fi
-
-s 用来判断文件是否不为空。如果要将空文件删除,首先要判断文件是否为空,对于非空的文件删除要谨慎。下面通过一个例子说明。
-
想创建一个空文件:
touch newfile ls -l -rw-rw-r--. 1 hadoop01 hadoop01 0 3 月 1 11:11 newfile
-
判断 newfile 文件是否为空。
#!/bin/bash file=/home/hadoop01/bash01/newfile # 判断文件是否不为空 if [ -s "$file" ] then echo "$file is a non empty file" else echo "$file is an empty file" fi # 向文件中追加内容 echo "We are learning Bash Shell!" >> $file # 判断文件是否不为空 if [ -s "$file" ] then echo "$file is a non empty file" echo "The contents fo the file:" # 显示文件尾部的内容 tail $file else echo "$file is an empty file" fi
-
-
-w 用来判断当前用户对文件是否有写权限,下面通过例子说明。
#!/bin/bash # 判断当前用户是否是 hadoop01 if [ "$USER" = "hadoop01" ] then cd $HOME/bash01 # 创建一个新的空文件 touch logfile # 去掉 yarn 用户的文件写权限 chmod u-w logfile # 判断当前用户 yarn 对 logfile 文件是否有写权限 if [ -w "logfile" ] then # 这段代码不会执行,因为用户没有写权限 echo "You have write permission!" echo "Not executed!" else echo "You do not have permission to write!" fi # 为 yarn 用户增加对 logfile 文件的写权限 chmod u+w logfile if [ -w "logfile" ] then # 这段代码会执行 echo "You already have permission to write!" echo "You have permission to write!" >> logfile else echo "You do not have permission to write!" echo "Not executed!" fi else # 如果不是 hadoop01 用户没有操作权限 echo "You do not have permission!" fi
-
-x 用来判断用户对文件是否有执行权限,通常的使用场景是在脚本中需要执行其他的脚本,要判断用户对脚本是否有执行权限,如果用户拥有脚本的执行权限则执行脚本,否则提示信息或修改脚本的执行权限。下面通过例子说明。
-
首先创建一个测试执行脚本 bash31_1.sh 并去掉 hadoop01 用户的执行权限:
#!/bin/bash echo "Bash Shell script action!"
-
bash31.sh:
#!/bin/bash file=/home/yarn/bash01/bash31_1.sh # 取消文件属主的执行权限 chmod u-x $file if [ "$USER" = "yarn" ] then # 判断文件是否有执行权限 if [ -x "$file" ] then echo "Not executed!" else # 增加用户的执行权限 chmod u+x $file # 执行脚本 $file fi else echo "You do not have premission!" fi
-
-
-
-O 用来判断当前用户是否是文件的属主。
-
首先使用 root 用户的权限创建一个文件 rootfile,然后使用 hadoop01 用户创建一个 yarnfile 文件:
-rw-r--r--. 1 root root 15 3 月 1 12:50 rootfile -rw-rw-r--. 1 yarn hadoop01 15 3 月 1 12:55 yarnfile
-
下面通过脚本说明-O 的使用方法。
#!/bin/bash yarnfile=/home/hadoop01/bash01/hadoop01file rootfile=/home/hadoop01/bash01/rootfile if [ "$USER" = "hadoop01" ] then # 判断文件 hadoop01file 的属主是否是当前用户 if [ -O "$hadoop01file" ] then # 会执行 echo "$hadoop01file is owner user hadoop01!" else echo "Not executed!" fi # 判断 rootfile 文件的属主是否是当前用户 if [ -O "$rootfile" ] then echo "Not executed!" else # 会执行 echo "$rootfile is not owner user hadoop01!" fi else echo "You do not have permission!" fi
-
-
-G 用来判断文件的默认组是否与当前用户的组相同,使用较少,下面通过例子说明。
#!/bin/bash yarnfile=/home/hadoop01/bash01/hadoop01file rootfile=/home/hadoop01/bash01/rootfile if [ "$USER" = "hadoop01" ] then # 判断文件的默认组是否和当前用户是同一个组 if [ -G "$hadoop01file" ] then # 会执行 echo "With the user hadoop01 with a group! " else echo "Not executed!" fi # 判断文件的默认组是否和当前用户是同一个组 if [ -G "$rootfile" ] then echo "Not executed!" else # 会执行 echo "With is not the user hadoop01 with a group!" fi else echo "You do not have permission!" fi