如果函数内部不符合条件,则跳过 bash while 循环

Skip bash while loop if function inside fails a condition

我有一个 while 循环,它逐行读取文件并将该行传递给循环内的多个函数或嵌套函数。如果其中一个函数发现错误,我希望 while 循环跳过该迭代并转到下一个。

我确实进行了很多搜索并尝试了不同的方法,但是使用“继续跳过 while 循环”是唯一的解决方案,但它似乎并没有帮助。我不确定在哪里或如何寻找这样的东西。是否有解决此问题的解决方案或不同的方法?感谢您的帮助。

   function2(){
   "if some condition that uses $test_name fails, skip the while loop"
  }

  function3(){
   do something
  }

  main_function (){
    do something to $test_name
    function2 $test_name
    function3 $test_name
  }

  while true read -r line; do
    if [[ ! "${line}" =~ ^# && ! -z "${line}" ]]; then
       test_name=$line
        main_function  $test_name 
    fi
 done < $OS_LIST

好吧,如果测试失败,在函数 2 中:

return 1

在主函数中:

if [[ $? -eq 0 ]]; then
   function3 $test_name
else
   return
fi

希望能帮到你

我的看法 -

$: cat failout
#! /bin/env bash

OS_LIST=os_list

func1() {
  if [[ -z "" ]]
  then echo "ERROR - Empty string!"
       return 1
  fi
}

func2() {
  grep -q foo <<< "" || { echo "ERROR - no 'foo'!"; return 1; }
}

func3() { echo "all good here"; }

mainfunc() {
  func1 "" || return 1
  func2 "" || return 1
  func3 "" || return 1
}

while read -r line
do echo "before:[$line]"
   mainfunc "$line" || { echo test failed; continue; }
   echo all tests passed.
done < <( grep -Ev '^[[:space:]]*(#.*)*$' $OS_LIST )

请注意,循环会在读取之前使用 grep 删除注释和空行。

输入文件,os_list,带有行号

$: vi os_list
  1
  2
  3
  4   # shan't
  5
  6 foo bar other stuff
  7
  8 just foo
  9
 10 footed...
 11
 12 bar, without any required string!
 13
 14 more foo
 15
 16

郑重声明,这些空行中有些确实有空格,有些则没有。 结果:

$: failout
before:[foo bar other stuff]
all good here
all tests passed.
before:[just foo]
all good here
all tests passed.
before:[footed...]
all good here
all tests passed.
before:[bar, without any required string!]
ERROR - no 'foo'!
test failed
before:[more foo]
all good here
all tests passed.

希望对您有所帮助。它当然可以更好。 欢迎提问

首先,编写函数,使它们 return 如果失败则为非零状态,如果成功则为零(实际上,作为一般的良好做法,您无论如何都应该这样做)。像这样:

function2() {
    if some condition that uses $test_name fails; then
        echo "test condition failed in function2" >&2    # Error messages should be sent to stderr
        return 1
    fi
    # Code here will only be executed if the test succeeded
    do_something || return 1
    # Code here will only be executed if the test AND do_something both succeeded
    do_something_optional    # No error check here means it'll continue even if this fails
    do_something_else || {
        echo "do_something_else failed in function2" >&2
        return 1
    }
    return 0    # This is actually optional. By default it'll return the status
                # of the last command in the function, which must've succeeded
}

请注意,您可以根据情况在此处混合样式(if vs || vs 其他)。一般来说,使用最清晰的风格,因为你最大的敌人是对代码的作用感到困惑。

然后,在主函数中,你可以检查每个子函数的退出状态,如果其中任何一个失败,尽早return:

main_function (){
    do something to "$test_name" || return 1    # BTW, you should double-quote variable references
    function2 "$test_name" || return 2    # optional: you can use different statuses for different problems
    function3 "$test_name"  || return 1
}

如果你需要跳过主循环的结尾,那就是你要使用的地方 continue:

while true read -r line; do
    if [[ ! "${line}" =~ ^# && ! -z "${line}" ]]; then
        test_name=$line
        main_function "$test_name" || continue
        echo "Finished processing: $line" >&2    # Non-error status messages also go to stderr
    fi
done < "$OS_LIST"