我有一个while循环,它逐行读取文件,并将该行传递给循环内的多个函数或嵌套函数。如果函数之一发现错误,我希望while循环跳过该迭代并转到下一个迭代。
我确实做了很多搜索,并尝试了不同的方法,但是使用'continue跳过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
答案 0 :(得分:2)
我愿意-
$: cat failout
#! /bin/env bash
OS_LIST=os_list
func1() {
if [[ -z "$1" ]]
then echo "ERROR - Empty string!"
return 1
fi
}
func2() {
grep -q foo <<< "$1" || { echo "ERROR - no 'foo'!"; return 1; }
}
func3() { echo "all good here"; }
mainfunc() {
func1 "$1" || return 1
func2 "$1" || return 1
func3 "$1" || 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.
希望有帮助。肯定会更好。 欢迎提问。
答案 1 :(得分:2)
首先,编写函数,以便它们在失败时返回非零状态,在成功时返回零(实际上,作为一般的好习惯,您应该这样做)。像这样:
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
与||
与其他任何样式)。通常,请使用最清晰的样式,因为您的最大敌人就是对代码的工作感到困惑。
然后,在主功能中,您可以检查每个子功能的退出状态,如果其中任何一个失败,则提早返回:
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"
答案 2 :(得分:1)
在功能2中,如果测试失败:
return 1
在主要功能中:
if [[ $? -eq 0 ]]; then
function3 $test_name
else
return
fi
希望它能提供帮助