Shell
3.1 运算符
3.1.1 算数运算符
在Shell脚本中,算术运算符用于执行基本的数学运算。Shell支持多种算术运算符,包括加、减、乘、除等。以下是关于Shell算术运算符的一些方法以及相应的示例说明:
加法:
a=10
b=20
c=$((a + b))
echo $c # 输出:30
$((a + b))
表示把a
和b
的值相加,并将结果赋给变量c
。
减法:
a=30
b=20
c=$((a - b))
echo $c # 输出:10
$((a - b))
表示把a
和b
的值相减,并将结果赋给变量c
。
乘法:
a=10
b=20
c=$((a * b))
echo $c # 输出:200
$((a * b))
表示把a
和b
的值相乘,并将结果赋给变量c
。
除法:
a=30
b=3
c=$((a / b))
echo $c # 输出:10
$((a / b))
表示把a
和b
的值相除,并将结果赋给变量c
。需要注意的是,如果除数为0,会导致脚本执行错误。
取余:
a=30
b=4
c=$((a % b))
echo $c # 输出:2
$((a % b))
表示把a
除以b
的余数,并将结果赋给变量c
。
自增:
a=10
((a++))
echo $a # 输出:11
((a++))
表示将变量a
的值自增1,即等价于a = a + 1
。
自减:
a=10
((a--))
echo $a # 输出:9
((a--))
表示将变量a
的值自减1,即等价于a = a - 1
。
通过这些算术运算符,可以在Shell脚本中执行基本的数学运算,对变量进行自增和自减操作。需要注意的是,算术运算符需要使用$((...))
或((...))
语法进行运算,而不能直接使用数学表达式。
3.1.2 关系运算符
在Shell脚本中,关系运算符用于比较两个值之间的关系,返回布尔值(真或假)。Shell提供了多种关系运算符,包括 -eq
、-ne
、-gt
、-lt
、-ge
和 -le
,分别用于判断相等、不相等、大于、小于、大于等于和小于等于等关系。以下是关于Shell关系运算符的详细介绍以及相应的示例说明:
-eq:相等
-eq
用于判断两个值是否相等,如果相等则返回true。
示例:
a=10
b=10
if [ $a -eq $b ]; then
echo "a 等于 b"
fi
输出:
a 等于 b
-ne:不相等
-ne
用于判断两个值是否不相等,如果不相等则返回true。
示例:
a=10
b=20
if [ $a -ne $b ]; then
echo "a 不等于 b"
fi
输出:
a 不等于 b
-gt:大于
-gt
用于判断左边的值是否大于右边的值,如果是则返回true。
示例:
a=30
b=20
if [ $a -gt $b ]; then
echo "a 大于 b"
fi
输出:
a 大于 b
-lt:小于
-lt
用于判断左边的值是否小于右边的值,如果是则返回true。
示例:
a=30
b=40
if [ $a -lt $b ]; then
echo "a 小于 b"
fi
输出:
a 小于 b
-ge:大于等于
-ge
用于判断左边的值是否大于等于右边的值,如果是则返回true。
示例:
a=30
b=30
if [ $a -ge $b ]; then
echo "a 大于等于 b"
fi
输出:
a 大于等于 b
-le:小于等于
-le
用于判断左边的值是否小于等于右边的值,如果是则返回true。
示例:
a=30
b=30
if [ $a -le $b ]; then
echo "a 小于等于 b"
fi
输出:
a 小于等于 b
通过使用这些关系运算符,可以在Shell脚本中进行条件判断,根据不同的关系运算结果执行相应的操作。需要注意的是,关系运算符需要在方括号中使用,并且变量周围需要有空格,以确保运算符正确解析。
3.1.3 逻辑运算符
在Shell脚本中,逻辑运算符用于对多个条件进行逻辑操作,返回布尔值(真或假)。Shell提供了多种逻辑运算符,包括逻辑或(-o
或 ||
)、逻辑与(-a
或 &&
)、逻辑非(!
)等。以下是关于Shell逻辑运算符的详细介绍以及相应的示例说明:
逻辑或(-o 或 ||)
-o
或 ||
表示逻辑或运算符,左右两边的条件只要有一个满足就返回 true。
示例:
a=10
b=20
if [ $a -eq 10 -o $b -eq 30 ]; then
echo "a 等于 10 或者 b 等于 30"
fi
输出:
a 等于 10 或者 b 等于 30
逻辑与(-a 或 &&)
-a
或 &&
表示逻辑与运算符,左右两边的条件都满足才返回 true。
示例:
a=10
b=20
if [ $a -eq 10 -a $b -eq 20 ]; then
echo "a 等于 10 并且 b 等于 20"
fi
输出:
a 等于 10 并且 b 等于 20
逻辑非(!)
!
表示逻辑非运算符,对条件取反,如果条件为假,则返回 true。
示例:
a=10
if ! [ $a -eq 20 ]; then
echo "a 不等于 20"
fi
输出:
a 不等于 20
可以组合使用逻辑运算符,实现复杂的条件判断。例如,使用逻辑或和逻辑与运算符进行混合操作:
示例:
a=10
b=20
c=30
if [ $a -eq 10 -a $b -ne 30 ] || [ $c -gt 20 ]; then
echo "a 等于 10 并且 b 不等于 30,或者 c 大于 20"
fi
输出:
a 等于 10 并且 b 不等于 30,或者 c 大于 20
通过使用这些逻辑运算符,可以在Shell脚本中对多个条件进行逻辑操作,根据不同的逻辑运算结果执行相应的操作。需要注意的是,在条件判断语句中,逻辑运算符需要在方括号中使用,并且变量周围需要有空格,以确保运算符正确解析。
3.1.4 字符串运算符
在Shell脚本中,字符串运算符用于对字符串进行操作,返回布尔值(真或假)。Shell提供了多种字符串运算符,包括 -n
、-z
、=~
、==
、!=
、<
、>
、-le
和 -ge
等。以下是关于Shell字符串运算符的详细介绍以及相应的示例说明:
-n:非空
-n
用于判断字符串是否为非空,如果非空则返回 true。
示例:
a="hello"
if [ -n $a ]; then
echo "a 不为空"
fi
输出:
a 不为空
-z:空
-z
用于判断字符串是否为空,如果为空则返回 true。
示例:
a=""
if [ -z $a ]; then
echo "a 为空"
fi
输出:
a 为空
=~:匹配正则表达式
=~
用于匹配字符串与正则表达式,如果匹配成功则返回 true。
示例:
a="hello world"
if [[ $a =~ "world" ]]; then
echo "a 包含 world"
fi
输出:
a 包含 world
==:等于
==
用于判断两个字符串是否相等,如果相等则返回 true。
示例:
a="hello"
b="hello"
if [ $a == $b ]; then
echo "a 等于 b"
fi
输出:
a 等于 b
!=:不等于
!=
用于判断两个字符串是否不相等,如果不相等则返回 true。
示例:
a="hello"
b="world"
if [ $a != $b ]; then
echo "a 不等于 b"
fi
输出:
a 不等于 b
<:小于
<
用于判断一个字符串是否小于另一个字符串,如果是则返回 true。
示例:
a="apple"
b="banana"
if [ $a \< $b ]; then
echo "a 小于 b"
fi
输出:
a 小于 b
>:大于
>
用于判断一个字符串是否大于另一个字符串,如果是则返回 true。
示例:
a="banana"
b="apple"
if [ $a \> $b ]; then
echo "a 大于 b"
fi
输出:
a 大于 b
-le:小于等于
-le
用于判断一个字符串是否小于或等于另一个字符串,如果是则返回 true。
示例:
a="apple"
b="banana"
c="apple"
if [ $a \<= $b ] && [ $a -le $c ]; then
echo "a 小于等于 b,并且 a 小于等于 c"
fi
输出:
a 小于等于 b,并且 a 小于等于 c
-ge:大于等于
-ge
用于判断一个字符串是否大于或等于另一个字符串,如果是则返回 true。
示例:
a="banana"
b="apple"
c="banana"
if [ $a \>= $b ] && [ $a -ge $c ]; then
echo "a 大于等于 b,并且 a 大于等于 c"
fi
输出:
a 大于等于 b,并且 a 大于等于 c
通过使用这些字符串运算符,可以在Shell脚本中对字符串进行条件判断,根据不同的字符串运算结果执行相应的操作。需要注意的是,在条件判断语句中,字符串运算符需要在方括号中使用,并且变量周围需要有空格,以确保运算符正确解析。
3.1.5 文件测试运算符
Shell 提供了丰富的文件测试运算符,用于检查文件的各种属性。下面是对一些常用的文件测试运算符的详细介绍以及相应的示例说明:
-e:文件存在
-e
用于检查文件是否存在,如果文件存在则返回 true。
示例:
file="example.txt"
if [ -e $file ]; then
echo "$file 存在"
fi
输出:
example.txt 存在
-f:普通文件
-f
用于检查文件是否为普通文件,而不是目录或设备文件等特殊类型的文件。如果是普通文件则返回 true。
示例:
file="example.txt"
if [ -f $file ]; then
echo "$file 是普通文件"
fi
输出:
example.txt 是普通文件
-d:目录
-d
用于检查文件是否为目录,如果是目录则返回 true。
示例:
dir="example"
if [ -d $dir ]; then
echo "$dir 是目录"
fi
输出:
example 是目录
-s:非空文件
-s
用于检查文件是否为非空文件,如果文件大小大于0则返回 true。
示例:
file="example.txt"
if [ -s $file ]; then
echo "$file 是非空文件"
fi
输出:
example.txt 是非空文件
-r:可读
-r
用于检查文件是否可读,如果文件可读则返回 true。
示例:
file="example.txt"
if [ -r $file ]; then
echo "$file 可读"
fi
输出:
example.txt 可读
-w:可写
-w
用于检查文件是否可写,如果文件可写则返回 true。
示例:
file="example.txt"
if [ -w $file ]; then
echo "$file 可写"
fi
输出:
example.txt 可写
-x:可执行
-x
用于检查文件是否可执行,如果文件可执行则返回 true。
示例:
file="script.sh"
if [ -x $file ]; then
echo "$file 可执行"
fi
输出:
script.sh 可执行
-nt 和 -ot:新于和旧于
-nt
用于检查文件是否比另一个文件新,而 -ot
用于检查文件是否比另一个文件旧。这两个运算符可以用于比较文件的时间戳。
示例:
file1="file1.txt"
file2="file2.txt"
if [ $file1 -nt $file2 ]; then
echo "$file1 比 $file2 新"
fi
输出:
file1.txt 比 file2.txt 新
通过使用这些文件测试运算符,可以在Shell脚本中轻松地检查文件的存在性、类型、权限以及时间戳等属性,从而根据文件的状态执行相应的操作。这些运算符为Shell脚本编程提供了强大的文件操作能力。
3.2 test命令
test
命令是用于在Shell脚本中进行条件测试的工具,它也可以用方括号 [ ]
的形式来使用,因为test
其实就是方括号的另一种表示方式。test
命令接受不同的选项和参数,用于测试文件属性、字符串比较、算术比较等,根据测试结果返回不同的退出状态码,以便在Shell脚本中进行条件判断。
下面是test
命令的一些常用选项和示例说明:
-
测试文件属性:
-
用法:
test -e file
-
描述:检查文件是否存在。
-
示例:
file="example.txt" if test -e $file; then echo "$file 存在" fi
-
-
字符串比较:
-
用法:
test string1 = string2
-
描述:检查两个字符串是否相等。
-
示例:
str1="hello" str2="world" if test $str1 = $str2; then echo "两个字符串相等" fi
-
-
整数比较:
-
用法:
test int1 -eq int2
-
描述:检查两个整数是否相等。
-
示例:
num1=10 num2=20 if test $num1 -eq $num2; then echo "两个整数相等" fi
-
-
文件比较:
-
用法:
test file1 -nt file2
和test file1 -ot file2
-
描述:
-nt
用于检查文件1是否比文件2新,而-ot
用于检查文件1是否比文件2旧。 -
示例:
file1="file1.txt" file2="file2.txt" if test $file1 -nt $file2; then echo "$file1 比 $file2 新" fi
-
-
复合条件测试:
-
用法:
test condition1 -a condition2
和test condition1 -o condition2
-
描述:
-a
表示逻辑与(and),-o
表示逻辑或(or)。 -
示例:
num=15 if test $num -gt 10 -a $num -lt 20; then echo "$num 大于10并且小于20" fi
-
除了直接使用test
命令以外,你也可以使用方括号的形式来进行条件测试,例如:
file="example.txt"
if [ -e $file ]; then
echo "$file 存在"
fi
无论是使用test
命令还是方括号形式,它们都能够帮助你在Shell脚本中进行条件判断,根据测试结果执行相应的操作。
3.3 Shell流程控制
Shell脚本中的流程控制可以帮助我们根据条件或循环来决定代码的执行路径。主要的流程控制结构包括条件语句(if-else)、循环语句(for、while、until)和跳转语句(break、continue)等。
下面是对Shell的流程控制结构的详细介绍以及相应的示例说明:
-
条件语句(if-else):
-
用法:
if condition; then # 条件为真时执行的代码块 else # 条件为假时执行的代码块 fi
-
描述:根据给定的条件判断,决定执行哪个代码块。
-
示例:
num=10 if [ $num -gt 0 ]; then echo "数字大于0" else echo "数字小于等于0" fi
-
-
循环语句(for):
-
用法:
for var in list; do # 循环体内执行的代码块 done
-
描述:遍历列表中的元素,每次迭代将列表中的一个元素赋值给变量,并执行对应代码块。
-
示例:
fruits=("apple" "banana" "orange") for fruit in ${fruits[@]}; do echo "水果:$fruit" done
-
-
多选择语句(case):
-
用法:
case value in pattern1) # 匹配模式1时执行的代码块 ;; pattern2) # 匹配模式2时执行的代码块 ;; pattern3|pattern4) # 匹配模式3或模式4时执行的代码块 ;; *) # 以上模式都不匹配时执行的代码块 ;; esac
-
case 语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
-
示例:
#!/bin/bash fruit="apple" case $fruit in "apple") echo "Selected fruit is Apple" ;; "banana") echo "Selected fruit is Banana" ;; "orange"|"kiwi") echo "Selected fruit is Orange or Kiwi" ;; *) echo "Unknown fruit" ;; esac
-
-
循环语句(while):
-
用法:
while condition; do # 循环体内执行的代码块 done
-
描述:只要条件为真,就会一直执行循环体内的代码块。
-
示例:
num=1 while [ $num -le 5 ]; do echo "当前数字:$num" num=$((num + 1)) done
-
-
循环语句(until):
-
用法:
until condition; do # 循环体内执行的代码块 done
-
描述:只要条件为假,就会一直执行循环体内的代码块。
-
示例:
num=1 until [ $num -gt 5 ]; do echo "当前数字:$num" num=$((num + 1)) done
-
-
跳转语句(break):
-
用法:
break
-
描述:跳出当前循环或选择结构,继续执行循环或选择结构之后的代码。
-
示例:
for num in 1 2 3 4 5; do if [ $num -eq 3 ]; then break fi echo "当前数字:$num" done
-
-
跳转语句(continue):
-
用法:
continue
-
描述:跳过当前循环中余下的代码,进入下一次循环迭代。
-
示例:
for num in 1 2 3 4 5; do if [ $num -eq 3 ]; then continue fi echo "当前数字:$num" done
-
通过使用这些流程控制结构,你可以根据条件或循环来控制Shell脚本中的代码执行。这些结构提供了灵活性和可扩展性,使得Shell脚本能够处理各种不同的情况和需求。
3.4 Shell函数
在Shell脚本编程中,函数是一种重要的流程控制结构,用于封装一段可重复使用的代码块。通过定义函数,你可以将一组相关的操作组合在一起,并在需要时调用它们。下面是对Shell的流程控制函数的详细介绍以及相应的示例说明:
1. 定义函数:
function_name() {
# 函数体内执行的代码块
# 可以包含变量、命令、流程控制语句等
}
或者
function function_name {
# 函数体内执行的代码块
# 可以包含变量、命令、流程控制语句等
}
2. 调用函数:
function_name
3. 函数的示例说明:
#!/bin/bash
# 定义一个简单的函数
say_hello() {
echo "Hello, World!"
}
# 调用函数
say_hello
在上面的示例中,我们定义了一个名为say_hello
的函数,它的功能是输出"Hello, World!"。然后,我们通过调用say_hello
函数来执行这段代码。
函数还可以接受参数,允许你向函数传递数据。下面是一个带有参数的函数的示例:
#!/bin/bash
# 定义一个带有参数的函数
greet() {
name=$1
echo "Hello, $name!"
}
# 调用函数,并传递参数
greet "Alice"
在上面的示例中,我们定义了一个名为greet
的函数,它接受一个参数name
。函数体内将参数赋值给变量name
,然后输出"Hello, $name!“。通过调用greet
函数并传递参数"Alice”,我们可以输出"Hello, Alice!"。
函数还可以返回值,在Shell脚本中使用return
语句来实现。下面是一个带有返回值的函数的示例:
#!/bin/bash
# 定义一个带有返回值的函数
add_numbers() {
num1=$1
num2=$2
sum=$(($num1 + $num2))
return $sum
}
# 调用函数,并接收返回值
result=$(add_numbers 10 20)
echo "Sum: $result"
在上面的示例中,我们定义了一个名为add_numbers
的函数,它接受两个参数num1
和num2
,计算它们的和并将结果赋给变量sum
。然后,我们使用return
语句返回sum
的值。通过调用add_numbers
函数并将返回值赋给变量result
,我们可以输出"Sum: 30"。
通过使用函数,你可以将一段代码封装起来,提高代码的可重用性和可维护性。函数可以接受参数、返回值,并且可以包含变量、命令、流程控制语句等,让你的Shell脚本更加灵活和功能强大。
4. Shell脚本必须以.sh后缀结尾吗
不是必须的,可以不加.sh。但扩展名sh代表shell,可以让人看到后缀就知道是shell脚本,是一种命名规范,所以建议加上。
在Linux中,脚本的后缀并不影响其是否可以执行。Shell脚本的可执行性是根据文件的权限属性来确定的。