条件判断

最后更新于:2022-04-02 03:53:33

[TOC] ## 中括号 / 双中括号 区别 相同点 1. 两个符号左右都要有空格分隔 2. 内部操作符与操作变量之间要有空格:如 `[[ "a" = "b" ]]` 3. 内部字符串或者${}变量尽量使用”” 双引号扩住 单中括号 [ ] 1. 字符串比较中,> < 需要写成 `\>` `\<` 进行转义 1. [ ] 中可以使用 –a –o 进行逻辑运算 1. [ ] 是bash 内置命令 双中括号 1. 字符串比较中,可以直接使用 > < 无需转义 1. [[ ]] 内部可以使用 && || 进行逻辑运算 1. [[ ]] 是bash keyword:[[ is a shell keyword ## if 结构 ``` if commands; then commands [elif commands; then commands...] [else commands] fi // 多个条件 if [ commands ] && [ commands ] ;then // code fi ``` 示例 ``` if test $USER = "foo"; then echo "Hello foo." else echo "You are not foo." fi ``` ## test 命令 ``` # 写法一 test expression # 写法二 [ expression ] # 写法三 [[ expression ]] ``` ``` # 写法一 if test -e /tmp/foo.txt ; then echo "Found foo.txt" fi # 写法二 if [ -e /tmp/foo.txt ] ; then echo "Found foo.txt" fi # 写法三 if [[ -e /tmp/foo.txt ]] ; then echo "Found foo.txt" fi ``` ### && || 逻辑运算 ``` $ command1 && command2 // command1 成功执行 command2 $ command1 || command2 // command1 失败执行 command2 ``` 示例1 ``` [ -d temp ] || mkdir temp ``` 示例2 ``` [[ -d "$dir_name" ]] && cd "$dir_name" && rm * ``` ## 判断表达式 ### 文件 / 目录 判断 * `[ -d file ]`:如果 file 存在并且是一个目录,则为`true`。 * `[ -e file ]`:如果 file 存在,则为`true`。 * `[ -f file ]`:如果 file 存在并且是一个普通文件,则为`true`。 * `[ -r file ]`:如果 file 存在并且可读(当前用户有可读权限),则为`true`。 * `[ -s file ]`:如果 file 存在且其长度大于零,则为`true`。 * `[ -w file ]`:如果 file 存在并且可写(当前用户拥有可写权限),则为`true`。 * `[ -x file ]`:如果 file 存在并且可执行(有效用户有执行/搜索权限),则为`true`。 * `[ file1 -nt file2 ]`:如果 FILE1 比 FILE2 的更新时间最近,或者 FILE1 存在而 FILE2 不存在,则为`true`。 * `[ file1 -ot file2 ]`:如果 FILE1 比 FILE2 的更新时间更旧,或者 FILE2 存在而 FILE1 不存在,则为`true`。 * `[ FILE1 -ef FILE2 ]`:如果 FILE1 和 FILE2 引用相同的设备和 inode 编号,则为`true`。 ### 字符串判断 * `[ string ]`:如果`string`不为空(长度大于0),则判断为真。 * `[ -n string ]`:如果字符串`string`的长度大于零,则判断为真。 * `[ -z string ]`:如果字符串`string`的长度为零,则判断为真。 * `[ string1 = string2 ]`:如果`string1`和`string2`相同,则判断为真。 * `[ string1 == string2 ]`等同于`[ string1 = string2 ]`。 * `[ string1 != string2 ]`:如果`string1`和`string2`不相同,则判断为真。 * `[ string1 '>' string2 ]`:如果按照字典顺序`string1`排列在`string2`之后,则判断为真。 * `[ string1 '<' string2 ]`:如果按照字典顺序`string1`排列在`string2`之前,则判断为真。 ### 整数判断 * `[ integer1 -eq integer2 ]`:如果`integer1`等于`integer2`,则为`true`。 * `[ integer1 -ne integer2 ]`:如果`integer1`不等于`integer2`,则为`true`。 * `[ integer1 -le integer2 ]`:如果`integer1`小于或等于`integer2`,则为`true`。 * `[ integer1 -lt integer2 ]`:如果`integer1`小于`integer2`,则为`true`。 * `[ integer1 -ge integer2 ]`:如果`integer1`大于或等于`integer2`,则为`true`。 * `[ integer1 -gt integer2 ]`:如果`integer1`大于`integer2`,则为`true`。 ### 正则判断 语法 `[[ string1 =~ regex ]]` 示例 ``` INT=-5 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then echo "INT is an integer." exit 0 else echo "INT is not an integer." >&2 exit 1 fi ``` ### 算术判断 ``` if ((3 > 2)); then echo "true" fi ``` ``` if [[ ! -d "$dir_name" ]]; then echo "No such directory: '$dir_name'" >&2 exit 1 fi if ! cd "$dir_name"; then echo "Cannot cd to '$dir_name'" >&2 exit 1 fi if ! rm *; then echo "File deletion failed. Check results" >&2 exit 1 fi ``` ## case 结构 格式 ``` case expression in pattern ) commands ;; pattern ) commands ;; ... esac ``` case的匹配模式可以使用各种通配符 ``` a):匹配a。 a|b):匹配a或b。 [[:alpha:]]):匹配单个字母。 ???):匹配3个字符的单词。 *.txt):匹配.txt结尾。 *):匹配任意输入,通过作为case结构的最后一个模式 ``` Bash 4.0之前,case结构只能匹配一个条件,然后就会退出case结构。Bash 4.0之后,允许匹配多个条件,这时可以用;;&终止每个条件块 示例1 ``` #! /bin/bash echo -n "输入1~3 的数字" read char case $char in 1)echo 1;; 2)echo 2;; 3)echo 3;; *)echo "输入不符合要求" esac ``` 示例2 ``` #!/bin/bash OS=$(uname -s) case "$OS" in FreeBSD) echo "This is FreeBSD" ;; Darwin) echo "This is Mac OSX" ;; AIX) echo "This is AIX" ;; Minix) echo "This is Minix" ;; Linux) echo "This is Linux" ;; *) echo "Failed to identify this OS" ;; esac ``` 示例3 满足条件后终止匹配 ``` read -n 1 -p "Type a character > " echo case $REPLY in [[:upper:]]) echo "'$REPLY' is upper case." ;;& [[:lower:]]) echo "'$REPLY' is lower case." ;;& [[:alpha:]]) echo "'$REPLY' is alphabetic." ;;& esac ```
';