如果函数内部不符合条件,则跳过 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"
我有一个 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"