首页 > 解决方案 > 我的 shell 脚本“break”语句不起作用

问题描述

我想打破我的嵌套 while 循环。

下面是我在我的代码中尝试过的,

while [itretative condition]
do
   ...
   ...
      cat test1.json | while read line
      do
        ...
        ...
           cat test2.json | while read line
           do
             ...
             ...
                if [ "$taskstatus" = "RUNNING" ]
#when my task status reach running, i want to stop the script execution and end it.
                break 3       #break 3 or exit is not working for me.
                fi
           done
      done
done

请建议我如何实现这一目标?

标签: bashshellloopsnested-loopsbreak

解决方案


每当您使用管道时,都会创建一个子外壳。Neiterbreak也不会exit在子壳边界上工作。

Eventrap不适用于子外壳边界。但是该选项set -E告诉 Bash 继承父 shell 的错误处理程序。通过这种方式,您可以保留一个特殊的退出代码来实现break逻辑。

以下代码分为外壳和子外壳,它们使用管道运行您的代码并创建更多子外壳。

子shell不继承外壳的错误处理程序,因为默认情况下禁用了陷阱处理程序继承。外壳的错误处理程序只检查保留的退出代码(示例中的 42)并将其视为无错误。

在第一个子 shell 中,错误处理程序继承由set -E. 这意味着所有子 shell 共享相同的错误处理程序。子 shell 错误处理程序只是传递错误代码并终止 shell。这样所有的子shell都被终止了。

#! /bin/bash

err()
{
  local err=$?
  if (( err == 42 )); then
    exit
  else
    exit $err
  fi
}
trap err ERR

(
  set -E

  err()
  {
    local err=$?
    exit $err
  }

  trap err ERR

  printf "%s\n" a b c | while read i; do
    echo $i
    printf "%s\n" x y z | while read j; do
      echo $j
      exit 42
    done
  done
)

推荐阅读