简单if-then
#!/bin/bash
if pwd
then
echo "It worked"
fi
这个脚本在 if 行采用了 pwd 命令。如果命令成功结束, echo 语句就会显示该文本字符串。在
命令行运行该脚本时,会得到如下结果
shell执行了 if 行中的 pwd 命令。由于退出状态码是 0 ,它就又执行了 then 部分的 echo 语句。
下面是另外一个例子
if IamNotaCommand
then
echo "It worked"
fi
echo "We are outside the if statement"
if-then-else 语句
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
then
echo "The bash files for user $testuser are:"
ls -a /home/$testuser/.b*
echo
else
echo "The user $testuser does not exist on this system."
echo
fi
嵌套 if
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
then
echo "The user $testuser exists on this system."
else
echo "The user $testuser does not exist on this system."
if ls -d /home/$testuser/
then
echo "However, $testuser has a directory."
fi
fi
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
then
echo "The user $testuser exists on this system."
#
elif ls -d /home/$testuser
then
echo "The user $testuser does not exist on this system."
echo "However, $testuser has a directory."
#
else
echo "The user $testuser does not exist on this system."
echo "And, $testuser does not have a directory."
fi
test 命令
到目前为止,在 if 语句中看到的都是普通shell命令。你可能想问, if-then 语句是否能测试
命令退出状态码之外的条件。
答案是不能。但在bash shell中有个好用的工具可以帮你通过 if-then 语句测试其他条件。
test 命令提供了在 if-then 语句中测试不同条件的途径。如果 test 命令中列出的条件成立,
test 命令就会退出并返回退出状态码 0 。这样 if-then 语句就与其他编程语言中的 if-then 语句
以类似的方式工作了。如果条件不成立, test 命令就会退出并返回非零的退出状态码,这使得
if-then 语句不会再被执行
if test
then
echo "No expression returns a True"
else
echo "No expression returns a False"
fi
变量 my_variable 中包含有内容( Full ),因此当 test 命令测试条件时,返回的退出状态
为 0 。这使得 then 语句块中的语句得以执行。
如你所料,如果该变量中没有包含内容,就会出现相反的情况
my_variable="Full"
#
if test $my_variable
then
echo "The $my_variable expression returns a True"
#
else
echo "The $my_variable expression returns a False"
fi
bash shell提供了另一种条件测试方法,无需在 if-then 语句中声明 test 命令
if [ condition ]
then
commands
fi
方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,
否则就会报错。
数值比较
value1=10
value2=11
#
if [ $value1 -gt 5 ]
then
echo "The test value"
fi
#
if [ $value1 -eq $value2 ]
then
echo "The values are"
else
echo "The values are"
fi
bash shell只能处理整数,单纯的输出浮点型变量的值可以但不能用作测试条件
字符串比较
testuser=baduser
#
if [ $USER != $testuser ]
then
echo "This is not $testuser"
else
echo "Welcome $testuser"
fi
字符串顺序
要测试一个字符串是否比另一个字符串大就是麻烦的开始。当要开始使用测试条件的大于或
小于功能时,就会出现两个经常困扰shell程序员的问题:
大于号和小于号必须转义,否则shell会把它们当作重定向符号,把字符串值当作文件
名;
大于和小于顺序和 sort 命令所采用的不同。
在编写脚本时,第一条可能会导致一个不易察觉的严重问题。下面的例子展示了shell脚本编
程初学者时常碰到的问题
字符串大小
val1=testing
val2=''
#
if [ -n $val1 ]
then
echo "The string '$val1'"
else
echo "The string '$val1'"
fi
#
if [ -z $val2 ]
then
echo "The string '$val2'"
else
echo "The string '$val2'"
fi
#
if [ -z $val3 ]
then
echo "The string '$val3'"
else
echo "The string '$val3'"
fi
这个例子创建了两个字符串变量。 val1 变量包含了一个字符串, val2 变量包含的是一个空
字符串。后续的比较如下:
if [ -n $val1 ]
判断 val1 变量是否长度非0,而它的长度正好非0,所以 then 部分被执行了。
if [ -z $var2 ]
判断 val2 变量是否长度为0,而它正好长度为0,所以 then 部分被执行了。
12
if [ -z $val3 ]
判断 val3 变量是否长度为0。这个变量并未在shell脚本中定义过,所以它的字符串长度仍然
为0,尽管它未被定义过
文件比较
检查目录
jump_directory=/home/arthur
#
if [ -d $jump_directory ]
then
echo "The $jump_directory directory exists"
cd $jump_directory
ls
else
echo "The $jump_directory directory does not exist"
fi
-e 比较允许你的脚本代码在使用文件或目录前先检查它们是否存在
location=$HOME
file_name="sentinel"
#
if [ -e $location ]
then #Directory does exist
echo "OK on the $location directory."
echo "Now checking on the file, $file_name."
#
if [ -e $location/$file_name ]
then #File does exist
echo "OK on the filename"
echo "Updating Current Date..."
date >> $location/$file_name
#
else #File does not exist
echo "File does not exist"
echo "Nothing to update"
fi
#
else
#Directory does not exist
echo "The $location directory does not exist."
echo "Nothing to update"
fi
检查文件
-e 比较可用于文件和目录。要确定指定对象为文件,必须用 -f 比较
item_name=$HOME
echo
echo "The item being checked: $item_name"
echo
#
if [ -e $item_name ]
then #Item does exist
echo "The item, $item_name, does exist."
echo "But is it a file?"
echo
#
if [ -f $item_name ]
then #Item is a file
echo "Yes, $item_name is a file."
#
else #Item is not a file
echo "No, $item_name is not a file."
fi
#
else
#Item does not exist
echo "The item, $item_name, does not exist."
echo "Nothing to update"
fi
检查是否可读
pwfile=/etc/shadow
#
# first, test if the file exists, and is a file
if [ -f $pwfile ]
then
# now test if you can read it
if [ -r $pwfile ]
then
tail $pwfile
else
echo "Sorry, I am unable to read the $pwfile file"
fi
else
echo "Sorry, the file $file does not exist"
fi
检查空文件
file_name=$HOME/sentinel
#
if [ -f $file_name ]
then
if [ -s $file_name ]
then
echo "The $file_name file exists and has data in it."
echo "Will not remove this file."
#
else
echo "The $file_name file exists, but is empty."
echo "Deleting empty file..."
rm $file_name
fi
else
echo "File, $file_name, does not exist."
fi
检查是否可写
item_name=$HOME/nurmemet
echo
echo "The item being checked: $item_name"
echo
if [ -w $item_name ]; then
echo "yes"
else
echo "no"
fi
检查文件是否可以执行
item_name=test6.sh
echo
echo "The item being checked: $item_name"
echo
if [ -x test6.sh ]
then
echo "yes"
else
echo "no"
fi
检查所属关系
else
echo "Sorry, you are not the owner of the /etc/passwd file"
fi
检查默认属组关系
if [ -G $HOME/testing ]
then
echo "You are in the same group as the file"
else
echo "The file is not owned by your group"
fi
检查文件日期
复合条件测试
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
if [ -d $HOME ] && [ -w $HOME/testing ]
then
echo "The file exists and you can write to it"
else
echo "I cannot write to the file"
fi
if-then 的高级特性
bash shell提供了两项可在 if-then 语句中使用的高级特性:
用于数学表达式的双括号
用于高级字符串处理功能的双方括号
后面几节将会详细描述每一种特性
双括号命令允许你在比较过程中使用高级数学表达式。 test 命令只能在比较中使用简单的
算术操作。双括号命令提供了更多的数学符号,这些符号对于用过其他编程语言的程序员而言并不陌生
val1=10
#
if (( $val1 ** 2 > 90 ))
then
(( val2 = $val1 ** 2 ))
echo "The square of $val1 is $val2"
fi
使用双方括号
双方括号里的 expression 使用了 test 命令中采用的标准字符串比较。但它提供了 test 命
令未提供的另一个特性——模式匹配(pattern matching)
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry, I do not know you"
fi
case 命令
case 命令会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么shell会执行
为该模式指定的命令。可以通过竖线操作符在一行中分隔出多个模式模式。星号会捕获所有与已
知模式不匹配的值
case $USER in
# 用户名如果是rich 或者 barbara
rich | barbara)
echo "Welcome, $USER"
echo "Please enjoy your visit";;
# 如果用户名为testing
testing)
echo "Special testing account";;
# 如果用户名为jessica
jessica)
echo "Do not forget to log off when you're done";;
# 如果上面的case都不匹配
*)
echo "Sorry, you are not allowed here";;
esac