8.0 KiB
原创
: Shell流程控制:if 分支结构
Shell流程控制:if 分支结构
流程控制:if 分支结构
if
x=5
if [ $x = 5 ]; then
echo "x equals 5."
else
echo "x does not equal 5."
fi
echo $?
查看命令执行返回的状态。经常与 if 一块使用的命令是 test,它执行各种各样的检查与比较:
test expression
[ expression ]
测试文件表达式:
|表达式|如果下列条件为真则返回True |------ |file1 -ef file2|file1 和 file2 拥有相同的索引号(通过硬链接两个文件名指向相同的文件)。 |file1 -nt file2|file1新于 file2。 |file1 -ot file2|file1早于 file2。 |-b file|file 存在并且是一个块(设备)文件。 |-c file|file 存在并且是一个字符(设备)文件。 |-d file|file 存在并且是一个目录。 |-e file|file 存在。 |-f file|file 存在并且是一个普通文件。 |-g file|file 存在并且设置了组 ID。 |-G file|file 存在并且由有效组 ID 拥有。 |-k file|file 存在并且设置了它的“sticky bit”。 |-L file|file 存在并且是一个符号链接。 |-O file|file 存在并且由有效用户 ID 拥有。 |-p file|file 存在并且是一个命名管道。 |-r file|file 存在并且可读(有效用户有可读权限)。 |-s file|file 存在且其长度大于零。 |-S file|file 存在且是一个网络 socket。 |-t fd|fd 是一个定向到终端/从终端定向的文件描述符 。 这可以被用来决定是否重定向了标准输入/输出错误。 |-u file|file 存在并且设置了 setuid 位。 |-w file|file 存在并且可写(有效用户拥有可写权限)。 |-x file|file 存在并且可执行(有效用户有执行/搜索权限)。
test_file () {
# test-file: Evaluate the status of a file
FILE=~/.bashrc
if [ -e "$FILE" ]; then
if [ -f "$FILE" ]; then
echo "$FILE is a regular file."
fi
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
if [ -r "$FILE" ]; then
echo "$FILE is readable."
fi
if [ -w "$FILE" ]; then
echo "$FILE is writable."
fi
if [ -x "$FILE" ]; then
echo "$FILE is executable/searchable."
fi
else
echo "$FILE does not exist"
# 函数中用return 语句来代替 exit 命令
return 1
fi
}
测试字符串表达式:
|表达式|如果下列条件为真则返回True |------ |string|string 不为 null。 |-n string|字符串 string 的长度大于零。 |-z string|字符串 string 的长度为零。 |string1 = string2string1 == string2|string1 和 string2 相同。 单或双等号都可以,不过双等号更受欢迎。 |string1 != string2|string1 和 string2 不相同。 |string1 > string2|sting1 排列在 string2 之后。 |string1 < string2|string1 排列在 string2 之前。
当与 test 一块使用的时候, > 和 < 表达式操作符必须用引号引起来(或者是用反斜杠转义)
整型表达式
测试整数表达式:
|表达式|如果为真… |------ |integer1 -eq integer2|integer1 等于 integer2。 |integer1 -ne integer2|integer1 不等于 integer2。 |integer1 -le integer2|integer1 小于或等于 integer2。 |integer1 -lt integer2|integer1 小于 integer2。 |integer1 -ge integer2|integer1 大于或等于 integer2。 |integer1 -gt integer2|integer1 大于 integer2。
更现代的测试版本
# 加强的 test 命令替代物
[[ expression ]]
# 添加的另一个功能是==操作符支持类型匹配
if [[ $FILE == foo.* ]]; then
...
string1 =~ regex
:匹配正则表达式则返回真
(( )) - 为整数设计
(( ))
复合命令,支持一套 完整的算术计算,(( ))
被用来执行算术真测试。如果算术计算的结果是非零值,则其测试值为真。
# 判断一个数的奇偶性
if (( ((INT % 2)) == 0)); then
echo "INT is even."
else
echo "INT is odd."
结合表达式
逻辑操作符:
|操作符|测试| and (( )) |------ |AND|-a|&& |OR|-o||| |NOT|!|!
控制操作符:分支的另一种方法
command1 && command2
command1 || command2
对于 && 操作符,先执行 command1,只有command1 执行成功后, 才会执行 command2。对于 || 操作符,先执行 command1,只有command1 执行失败后, 才会执行 command2。
读取键盘输入
read - 从标准输入读取数值
read [-options] [variable...]
#!/bin/bash
# read-integer: evaluate the value of an integer.
# -n 选项(其会删除输出结果末尾的换行符)的 echo 命令,来显示提示信息
echo -n "Please enter an integer -> "
read int
if [[ "$int" =~ ^-?[0-9]+$ ]]; then
if [ $int -eq 0 ]; then
echo "$int is zero."
else
if [ $int -lt 0 ]; then
echo "$int is negative."
else
echo "$int is positive."
fi
if [ $((int % 2)) -eq 0 ]; then
echo "$int is even."
else
echo "$int is odd."
fi
fi
else
echo "Input value is not an integer." >&2
exit 1
fi
alien@localhost:~ $ info-test
Please enter an integer -> 3
3 is positive.
3 is odd.
alien@localhost:~ $ info-test
Please enter an integer -> 6
6 is positive.
6 is even.
read 可以给多个变量赋值:
read var1 var2 var3 var4 var5
执行脚本时输入时以空格隔开,默认值为空,额外的输入数据会包含到最后一个变量中。
如果 read 命令之后没有列出变量名,则一个 shell 变量,默认的REPLY,将会包含 所有的输入:
read选项:
|选项|说明 |------ |-a array|把输入赋值到数组 array 中,从索引号零开始。我们 将在第36章中讨论数组问题。 |-d delimiter|用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符。 |-e|使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入。 |-n num|读取 num 个输入字符,而不是整行。 |-p prompt|为输入显示提示信息,使用字符串 prompt。 |-r|Raw mode. 不把反斜杠字符解释为转义字符。 |-s|Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助。 |-t seconds|超时. 几秒钟后终止输入。若输入超时,read 会返回一个非零退出状态。 |-u fd|使用文件描述符 fd 中的输入,而不是标准输入。
-t和-sp 选项,读取“秘密”输入,在特定的时间内 输入没有完成,就终止输入。
IFS
IFS 的默认值包含一个空格,一个 tab,和一个换行符,每一个都会把 字段分割开。
IFS=":" read user pw uid gid name home shell <<< "$file_info"
这一行由三部分组成:对一个变量的赋值操作,一个带有一串参数的 read 命令,和一个奇怪的新的重定向操作符。这个 <<<
操作符指示一个 here 字符串。不能把 管道用在 read 上----管道线 会创建子 shell。
菜单
#!/bin/bash
# read-menu: a menu driven system information program
clear
echo "
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
"
read -p "Enter selection [0-3] > "
if [[ $REPLY =~ ^[0-3]$ ]]; then
if [[ $REPLY == 0 ]]; then
echo "Program terminated."
exit
fi
if [[ $REPLY == 1 ]]; then
echo "Hostname: $HOSTNAME"
uptime
exit
fi
if [[ $REPLY == 2 ]]; then
df -h
exit
fi
if [[ $REPLY == 3 ]]; then
if [[ $(id -u) -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh $HOME
fi
exit
fi
else
echo "Invalid entry." >&2
exit 1
fi
第一部分显示菜单和用户输入。第二部分确认用户反馈,并执行 选择的行动。