判断条件参数详情
| File | Operators Details |
|---|---|
-e "$file" |
如果文件存在,则返回 true。 |
-d "$file" |
如果文件存在且是目录,则返回 true |
-f "$file" |
如果文件存在且是常规文件,则返回 true |
-h "$file" |
如果文件存在且是符号链接,则返回 true |
| String | Comparators Details |
|---|---|
-z "$str" |
如果字符串长度为零,则为 True |
-n "$str" |
如果字符串长度不为零,则为 True |
"$str" = "$str2" |
如果字符串 $str 等于字符串 $str2,则为 True。对于整数型数据来说不是最佳选择。可能有效,但不一致 |
"$str" != "$str2" |
如果字符串不相等,则为 True |
| Integer | Comparators Details |
|---|---|
"$int1" -eq "$int2" |
如果整数相等,则为 True |
"$int1" -ne "$int2" |
如果整数不相等,则为 True |
"$int1" -gt "$int2" |
如果 int1 大于 int2,则为 True |
"$int1" -ge "$int2" |
如果 int1 大于或等于 int2,则为 True |
"$int1" -lt "$int2" |
如果 int1 小于 int2,则为 True |
"$int1" -le "$int2" |
如果 int1 小于或等于 int2,则为 True |
Section 10.1: 有条件地执行命令列表
如何有条件地执行命令列表
任何内置命令、表达式或函数,以及任何外部命令或脚本,都可以使用 && (and) 和 || (or) 操作符有条件地执行。
例如,只有当 cd 命令被执行成功后才打印当前目录。
cd my_directory && pwd
同样,如果 cd 命令失败它也会退出,从而避免灾难的发生:
cd my_directory || exit
rm -rf *
在以这种方式组合多个语句时,重要的是要记住(与许多 C 风格语言不同)这些运算符没有优先级,并且是左关联的。
因此,这条语句将按照预期的方式运行...
cd my_directory && pwd || echo "No such directory"
- 如果
cd成功,则执行&& pwd,并打印出当前工作目录名。除非 pwd 失败(很少见),否则不会执行|| echo ...。 - 如果
cd失败,&& pwd将被跳过,|| echo ...将会运行。
但下面这个命令不会(如果你在想 “if...then...else”)...
cd my_directory && ls || echo "No such directory"
- 如果
cd失败,则跳过&& ls,执行|| echo ...。 - 如果
cd成功,则执行&& ls。 - 如果
ls成功,|| echo ...将被忽略。(目前情况良好) - 但是 ...... 如果
ls失败,|| echo ...也会被执行。
前一个命令是 ls,而不是 cd。
为什么要在命令列表中使用条件执行
条件执行比 if...then 要快一些,但它的主要优点是允许函数和脚本提前退出,或者说 “短路”。
与许多语言(如 C 语言)不同的是,在 C 语言中,内存是明确分配给结构体和变量等的(因此必须先进行分配),而 bash 则在暗处进行处理。在大多数情况下,我们不需要在离开函数之前清理任何东西。返回语句将取消分配函数本地的所有内容,并在堆栈上的返回地址重新开始执行。
因此,尽快从函数中返回或退出脚本可以避免不必要的代码执行,从而大大提高性能并减少系统负载。例如...
my_function () {
### ALWAYS CHECK THE RETURN CODE
# one argument required. "" evaluates to false(1)
[[ "$1" ]] || return 1
# work with the argument. exit on failure
do_something_with "$1" || return 1
do_something_else || return 1
# Success! no failures detected, or we wouldn't be here
return 0
}
Section 10.2: If 声明
if [[ $1 -eq 1 ]]; then
echo "1 was passed in the first parameter"
elif [[ $1 -gt 2 ]]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
结尾的 fi 是必要的,但 elif 和(或) else 子句可以省略。
then 前面的分号 ; 是将两条命令合并到一行的标准语法;只有将 then 移到下一行时才可以省略。
需要注意的是,括号 [[ 不是语法的一部分,但被视为一条命令;是这条测试命令的退出代码。因此,必须始终在括号内加入空格。
这也意味着可以测试任何命令的结果。如果命令的退出代码为 0,则认为语句为真。
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
数学表达式放在双括号内时,也会以同样的方式返回 0 或 1,并且也可以进行测试:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
你可能还会遇到带单括号的 if 语句。这些语句是在 POSIX 标准中定义的,保证可以在包括 Bash 在内的所有兼容 POSIX 的 shell 中运行。其语法与 Bash 中的非常相似:
if [ "$1" -eq 1 ]; then
echo "1 was passed in the first parameter"
elif [ "$1" -gt 2 ]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Section 10.3: 在数组上循环
for 循环:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
Or
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while 循环:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
Or
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Section 10.4: 使用 For 循环对数字进行列表迭代
#! /bin/bash
for i in {1..10}; do # {1..10} expands to "1 2 3 4 5 6 7 8 9 10"
echo $i
done
输出结果如下:
1
2
3
4
5
6
7
8
9
10
Section 10.5: continue 和 break
continue 的示例:
for i in [series]
do
command 1
command 2
if (condition) # Condition to jump over command 3
continue # skip to the next value in "series"
fi
command 3
done
break 的示例:
for i in [series]
do
command 4
if (condition) # Condition to break the loop
then
command 5 # Command if the loop needs to be broken
break
fi
command 6 # Command to run if the "condition" is never true
done
Section 10.6: 循环中断
中断多重循环:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break 2
done
done
输出:
a
a
中断单个循环:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
输出:
a
a
b
a
c
a
d
a
e
a
f
a
Section 10.7: While 循环
#! /bin/bash
i=0
while [ $i -lt 5 ] #While i is less than 5
do
echo "i is currently $i"
i=$[$i+1] #Not the lack of spaces around the brackets. This makes it a not a test expression
done #ends the loop
Watch that there are spaces around the brackets during the test (after the while statement). These spaces are necessary.
注意在判断过程中(while 语句之后),括号周围有空格。这些空格是必要的。
This loop outputs:
该循环输出:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
Section 10.8: 使用 C 风格语法的 For 循环
C 风格 for 循环的基本格式是:
for (( variable assignment; condition; iteration process ))
注意
-
在 C 风格 for 循环中对变量的赋值可以包含空格,这与通常的赋值不同
-
C 风格 for 循环中的变量不在前面加上 $。
示例
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
此外,我们还可以在 C 风格 for 循环中处理多个变量:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Section 10.9: Until 循环
Until 循环会一直执行到条件为 true
i=5
until [[ i -eq 10 ]]; do #Checks if i=10
echo "i=$i" #Print the value of i
i=$((i+1)) #Increment i by 1
done
Output:
i=5
i=6
i=7
i=8
i=9
当 i 达到 10 时,until 循环中的条件变为 true,循环结束。
Section 10.10: 带 case 的 Switch 语句
使用 case 语句,您可以将数值与一个变量匹配。
传递给 case 的参数会被展开,并尝试与每个模式匹配。
如果发现匹配,则执行 ;; 之前的命令。
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
模式不是正则表达式,而是 shell 模式匹配(又称 globs)。
Section 10.11: 不带单词列表参数的 For 循环
for arg; do
echo arg=$arg
done
没有单词列表参数的 for 循环将遍历位置参数。换句话说,上述示例等同于以下代码:
for arg in "$@"; do
echo arg=$arg
done
In other words, if you catch yourself writing for i in "$@"; do ...; done, just drop the in part, and write simply for i; do ...; done.
换句话说,如果你发现自己在写 for i in ”$@“; do ...; done,就去掉 in部分,直接写 for i; do ...; done。