Bash带操作符与命令参数的重试函数pgrep报错求助
Bash可复用重试函数的问题解决与实现思路
问题根源
你遇到的pgrep: only one pattern can be provided错误,本质是命令参数的分词问题:当你把pgrep -f 'sleep 10'作为单个字符串参数传递给函数时,Bash会解析掉引号,将其拆分为pgrep、-f、sleep、10四个独立参数。pgrep的-f选项仅接受一个匹配模式,因此会把sleep和10判定为两个模式,触发报错。
解决方案1:用数组传递命令参数
通过数组保存命令的各个参数,能完整保留参数的完整性,避免分词错误。以下是实现代码:
# 可复用重试函数:接受操作符和命令参数数组 retry() { local operator="$1" shift local -a cmd=("$@") # 将剩余参数转为数组 local max_attempts=5 # 最大重试次数 local delay=2 # 重试间隔(秒) local attempt=1 # 循环重试,直到操作符判断为真 until eval "[ $operator \"\$(""${cmd[@]}"")\" ]"; do if (( attempt >= max_attempts )); then echo "重试${max_attempts}次后仍失败" return 1 fi echo "第${attempt}次尝试失败,${delay}秒后重试..." (( attempt++ )) sleep "$delay" done echo "操作成功" return 0 }
使用示例
- 检查
sleep 10进程不存在(-z判断输出为空):
retry "-z" pgrep -f "sleep 10"
- 检查
sleep 10进程存在(! -z判断输出非空):
retry "! -z" pgrep -f "sleep 10"
解决方案2:传递自定义检查函数
如果需要更灵活的判断逻辑,可以直接传递一个检查函数给重试函数,完全规避参数传递的分词问题:
# 基于自定义函数的重试实现 retry_func() { local check_func="$1" local max_attempts=5 local delay=2 local attempt=1 until "$check_func"; do if (( attempt >= max_attempts )); then echo "重试${max_attempts}次后仍失败" return 1 fi echo "第${attempt}次尝试失败,${delay}秒后重试..." (( attempt++ )) sleep "$delay" done echo "操作成功" return 0 }
使用示例
- 先定义检查逻辑函数:
# 检查sleep 10进程是否未运行 check_sleep_not_running() { [ -z "$(pgrep -f 'sleep 10')" ] } # 检查sleep 10进程是否在运行 check_sleep_running() { [ ! -z "$(pgrep -f 'sleep 10')" ] }
- 调用重试函数:
retry_func check_sleep_not_running retry_func check_sleep_running
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

