shell脚本控制语句
条件语句
在Shell脚本中,if
语句用于基于条件执行不同的代码块。以下是一个具体的示例,展示了如何使用if
语句来检查一个文件是否存在,并根据结果执行不同的命令:
filename="example.txt"
if [ -e "$filename" ]; thenecho "文件 '$filename' 存在。"if [ -r "$filename" ]; thenecho "文件 '$filename' 可读。"elseecho "文件 '$filename' 不可读。"fi
elseecho "文件 '$filename' 不存在。"
fi
或者使用[[ ]]
,它提供了更多的灵活性和更强的字符串比较功能:
使用[[ ]]
时的一些额外特性:
- 模式匹配:可以使用
==
和!=
进行模式匹配。if [[ $file == *.txt ]]; thenecho "File is a text file." fi
- 正则表达式:可以使用
=~
进行正则表达式匹配。if [[ $file =~ \.txt$ ]]; thenecho "File is a text file." fi
- 逻辑操作符:可以直接在条件中使用
&&
和||
。if [[ -f "$file" && -s "$file" ]]; thenecho "File exists and is not empty." fi
[[ ]]提供了更多的功能和更好的灵活性,是Bash脚本中推荐使用的条件测试方式。而[]则更传统,兼容性更好,但在使用时需要更加小心。
注意事项:
- 条件测试中的
[ ]
或[[ ]]
是必要的,不要省略它们。 - []条件测试中的空格很重要,例如
[ -e "$filename" ]
中的空格不能省略。 - 使用
[[ ]]
而不是[ ]
可以避免一些常见的问题,比如单词分割和文件名中的空格问题。
循环语句
for循环语句
在Shell脚本中,for
循环用于重复执行一组命令,直到遍历完一个序列。以下是for
循环的基本结构:
基本语法
for variable in sequence
do# 命令
done
variable
:在每次迭代中,这个变量会被设置为序列中的一个值。sequence
:这是一个值的序列,可以是文件名列表、字符串或任何其他形式的列表。do
:这是循环体的开始。done
:这是循环体的结束。
示例
遍历文件名列表
for file in file1.txt file2.txt file3.txt
doecho "Processing $file"# 可以在这里添加更多的命令来处理每个文件
done
遍历字符串中的每个字符
for char in "Hello, World!"
doecho "$char"
done
遍历数组
array=("apple" "banana" "cherry")
#${array[@]} 引用数组中的所有元素
for item in "${array[@]}"
doecho "$item"
done
使用C风格的for循环
#这里必须使用(()),而不能使用()
for (( initialisation; condition; increment ))
do# 命令
done
initialisation
:在循环开始前执行的初始化命令。condition
:每次迭代前检查的条件。increment
:每次迭代后执行的命令。
解释(())
( … ) 内的代码块会在一个新的子shell中执行。在子shell中设置的 CHILD_VAR 变量只在子shell的上下文中有效,不会影响父shell中的环境。当子shell执行完毕后,它会被销毁,父shell继续执行,而子shell中的任何环境变化都不会保留。
这也意味着在两个for循环中,initialisation变量都可以叫i,而不必担心它们之间会有什么冲突。
使用单层括号 () 创建子shell的另一个常见用途是在循环中,这样可以确保每次迭代都在一个新的环境中执行,避免变量污染
示例
遍历数字序列
for ((i=0; i<5; i++))
doecho "Iteration $i"
done
while循环语句
在Shell脚本中,while
循环用于在某个条件为真时重复执行一组命令。以下是while
循环的基本结构:
基本语法
while [ condition ]
do# 命令
done
或者使用[[ ]]
,它提供了更多的灵活性和功能:
while [[ condition ]]
do# 命令
done
condition
:这是一个返回布尔值的条件表达式。只要条件为真,循环就会继续执行。do
:这是循环体的开始。done
:这是循环体的结束。
示例
** 打印0到4**
counter=0
while [ $counter -lt 5 ]
doecho "Counter is $counter"((counter++))
done
** 使用C风格的while循环**
while (( condition ))
do# 命令
done
condition
:这是一个返回布尔值的条件表达式,使用C风格的语法。
** 示例**
** 打印0到4**
i=0
while (( i < 5 ))
doecho "Iteration $i"((i++))
done
注意事项
此处[[]]和(())的解释与for循环语句中的解释一样。
until循环
在Shell脚本中,until
循环与while
循环相反,它用于在某个条件为真之前重复执行一组命令。until
循环会一直执行,直到条件变为真。以下是until
循环的基本结构:
基本语法
until [ condition ]
do# 命令
done
或者使用[[ ]]
,它提供了更多的灵活性和功能:
until [[ condition ]]
do# 命令
done
condition
:这是一个返回布尔值的条件表达式。只要条件为假,循环就会继续执行。do
:这是循环体的开始。done
:这是循环体的结束。
示例
打印0到4
counter=0
until [ $counter -ge 5 ]
doecho "Counter is $counter"((counter++))
done
c风格打印0到4
counter=0
until (( counter >= 5 ))
doecho "Counter is $counter"((counter++))
done
注意事项
此处[[]]和(())的解释与for循环语句中的解释一样。
until
循环是Shell脚本中非常有用的结构,适用于需要重复执行命令直到满足特定条件的情况。它特别适用于那些需要尝试多次直到成功的场景,例如等待某个服务启动或某个文件可用。
等待服务启动
#!/bin/bash# 服务名称
SERVICE_NAME="myservice"# 等待服务启动
until systemctl is-active --quiet "$SERVICE_NAME"; doecho "$SERVICE_NAME is not running, waiting..."sleep 5 # 等待5秒后再次检查
doneecho "$SERVICE_NAME has started."
等待文件可用
#!/bin/bash# 文件路径
FILE_PATH="/path/to/myfile.txt"# 等待文件可用
until [ -f "$FILE_PATH" ]; doecho "$FILE_PATH does not exist, waiting..."sleep 5 # 等待5秒后再次检查
doneecho "$FILE_PATH is available."
case-esac多选择语句
在Shell脚本中,case
语句提供了一种多选择的结构,允许根据一个值的不同来执行不同的代码块。case
语句的结构类似于其他编程语言中的switch
语句。以下是case
语句的基本结构:
基本语法
case 变量 in模式1)# 命令;;模式2)# 命令;;*)# 默认命令;;
esac
变量
:这是要匹配的变量。模式
:这是与变量值进行匹配的模式。模式可以是具体的值,也可以是使用通配符的模式。*)
:这是默认模式,如果前面的所有模式都不匹配,就会执行这里的命令。;;
:用于终止每个模式块。esac
:是case
的反向拼写,标志着case
语句的结束。
示例
以下是一个使用case
语句的示例,根据用户输入执行不同的命令:
echo "Enter a number (1, 2, 3, or 4):"
#从标准输入(通常是键盘)读取数据。
read numcase $num in1)echo "You entered one.";;2)echo "You entered two.";;3)echo "You entered three.";;4)echo "You entered four.";;*)echo "You did not enter a number between 1 and 4.";;
esac
在这个示例中,脚本提示用户输入一个数字,然后根据输入的数字执行相应的代码块。
注意事项
case
语句中的模式匹配是大小写敏感的,除非你明确地使用大写或小写来定义模式。- 可以使用
*
通配符来匹配任何字符串。 ;;
是必须的,它用来分隔不同的模式块。esac
是结束case
语句的关键字,不要漏掉。
case
语句是处理多个条件分支的有用工具,它使得脚本更加清晰和易于管理。
select-in语句
在Shell脚本中,select
语句用于创建一个菜单,允许用户从列表中选择一个选项。这是一种交互式的方式,可以让用户选择并执行相应的命令。以下是select
语句的基本结构:
基本语法
select variable in list
do# 命令break
done
variable
:这是每次用户选择一个选项时,将被设置为当前选项值的变量。list
:这是一个由空格分隔的选项列表,用户可以从中选择。do
:这是循环体的开始,每次用户做出选择后,都会执行这里的命令。break
:用于退出select
循环。如果不使用break
,循环将继续,即使已经执行了某些命令。
示例
以下是一个使用select
语句的示例,创建一个简单的菜单让用户选择:
echo "Please choose an option:"
select option in "Option 1" "Option 2" "Option 3" "Quit"
docase $option in"Option 1")echo "You chose Option 1.";;"Option 2")echo "You chose Option 2.";;"Option 3")echo "You chose Option 3.";;"Quit")echo "You chose to quit."break;;*)echo "Invalid option $REPLY.";;esac
done
运行结果
在这个示例中,脚本显示一个菜单,用户可以通过输入选项前的数字来选择。用户的选择将被存储在变量option
中,然后根据选择执行相应的命令。当用户选择"Quit"时,使用break
退出循环。
注意事项
select
语句是交互式的,它等待用户输入。$REPLY
是一个特殊的变量,它保存了用户在select
循环中的输入。- 如果用户输入的不是有效选项,可以使用
*)
来处理无效输入的情况。 break
命令用于退出select
循环,如果不使用break
,用户将被提示重新选择,直到手动退出脚本。
select
语句是创建用户友好菜单的有用工具,它使得脚本与用户的交互更加直观和简单。