bash 函数while循环中的return是如何处理的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20910112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How is return handled in a function while loop?
提问by Atomiklan
I have a function, and inside that function is a while loop.
我有一个函数,在该函数内部是一个 while 循环。
When I try to set a non local variable inside the while loop with an IF statement, then exit the entire function, suddenly the variable is no longer set?
当我尝试使用 IF 语句在 while 循环内设置非局部变量,然后退出整个函数时,突然不再设置该变量?
function EXAMPLE {
cat test.txt | while read LINE; do
if [ "$LINE" = "FAIL" ]; then
echo "Detected FAIL in file! Setting RETURN=fail and exiting function."
RETURN="fail"
return
fi
done
}
### START SCRIPT ###
EXAMPLE (Call example function)
echo "$RETURN"
For some reason, RETURN is empty. I have done this many many many times in the past though. Something about the while loop is preventing RETURN from being passed out of the function. Is "return" causing the script to break the loop and not the function?
出于某种原因,RETURN 为空。不过,我过去已经做过很多很多次了。关于 while 循环的某些事情阻止了 RETURN 被传递出函数。“返回”是否导致脚本中断循环而不是函数?
Thanks
谢谢
回答by chepner
The easiest solution is to avoid the subshell in the first place, by using input redirection instead of a pipeline.
最简单的解决方案是首先通过使用输入重定向而不是管道来避免使用 subshell。
function EXAMPLE {
while IFS= read -r line; do
if [ "$line" = "FAIL" ]; then
echo "Detected FAIL in file! Setting RETURN=fail and exiting function."
RETURN="fail"
return
fi
done < test.txt
}
In cases where the pipeline is unavoidable, bash
4.2 introduced the lastpipe
option, which when enabled allows the last command in a pipeline to run in the current shell, not a subshell. This way, the value assigned to RETURN
would be retained after the pipeline completes.
在管道不可避免的情况下,bash
4.2 引入了该lastpipe
选项,当启用该选项时,允许管道中的最后一个命令在当前 shell 中运行,而不是在子 shell 中运行。这样,分配给的值RETURN
将在管道完成后保留。
Even better, use the standard mechanism for signaling an error. Instead of setting the value of a custom parameter, just return a non-zero value:
更好的是,使用标准机制来发出错误信号。而不是设置自定义参数的值,只需返回一个非零值:
function EXAMPLE {
while IFS= read -r line; do
if [ "$line" = "FAIL" ]; then
echo "Detected FAIL in file! Exiting function with status 1."
return 1
fi
done < test.txt
}
回答by glenn Hymanman
When you use a pipeline in bash, all the commands within the pipeline are executed in subshells. That means variables cannot survive when the subshell exits. In this cate it's easy to remove the pipe
在 bash 中使用管道时,管道中的所有命令都在子 shell 中执行。这意味着当子 shell 退出时变量将无法生存。在这个 cate 中,很容易移除管道
function EXAMPLE {
while read LINE; do
if [ "$LINE" = "FAIL" ]; then
echo "Detected FAIL in file! Setting RETURN=fail and exiting function."
RETURN="fail"
return
fi
done < text.txt
}
I'd recommend not using ALL CAPS so often: one day you'll use a variable named PATH and then have to figure out why commands stop working.
我建议不要经常使用全部大写:有一天你会使用一个名为 PATH 的变量,然后必须弄清楚命令停止工作的原因。