我如何设置$?或 Bash 中的返回码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10448160/
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 do I set $? or the return code in Bash?
提问by JohnnyFromBF
I want to set a return value once so it goes into the while loop:
我想设置一次返回值,以便它进入 while 循环:
#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0
done
In order to get this working I need to set $? = 1
at the beginning, but that doesn't work.
为了让这个工作,我需要$? = 1
在开始时进行设置,但这不起作用。
采纳答案by Eugen Rieck
#!/bin/bash
RC=1
while [ $RC -eq 1 ]
do
#do something until it returns 0
RC=$?
done
回答by Paused until further notice.
You can set an arbitrary exit code by executing exit
with an argument in a subshell.
您可以通过exit
在子 shell 中使用参数执行来设置任意退出代码。
$ (exit 42); echo "$?"
42
So you could do:
所以你可以这样做:
(exit 1) # or some other value > 0 or use false as others have suggested
while (($?))
do
# do something until it returns 0
done
Or you can emulate a do while
loop:
或者你可以模拟一个do while
循环:
while
# do some stuff
# do some more stuff
# do something until it returns 0
do
continue # just let the body of the while be a no-op
done
Either of those guarantee that the loop is run at least one time which I believe is what your goal is.
其中任何一个都保证循环至少运行一次,我相信这就是您的目标。
For completeness, exit
and return
each accept an optional argument which is an integer (positive, negative or zero) which sets the return code as the remainder of the integer after division by 256. The current shell (or script or subshell*) is exited using exit
and a function is exited using return
.
为了完整性,exit
并且return
每个接受一个可选参数,它是一个整数(正,负或零),其通过256当前壳(或脚本或子外壳*)设置返回代码作为分割后的整数的剩余部分使用退出exit
并使用 退出函数return
。
Examples:
例子:
$ (exit -2); echo "$?"
254
$ foo () { return 2000; }; foo; echo $?
208
* This is true even for subshells which are created by pipes (except when both job control is disabled and lastpipe
is enabled):
* 即使对于由管道创建的子外壳也是如此(除非同时禁用和lastpipe
启用作业控制):
$ echo foo | while read -r s; do echo "$s"; exit 333; done; echo "$?"
77
Note that it's better to use break
to leave loops, but its argument is for the number of levels of loops to break out of rather than a return code.
请注意,最好使用break
离开循环,但它的参数是要跳出的循环级别数,而不是返回代码。
Job control is disabled using set +m
, set +o monitor
or shopt -u -o monitor
. To enable lastpipe
do shopt -s laspipe
. If you do both of those, the exit
in the preceding example will cause the while
loop andthe containing shell to bothexit and the final echo
there will not be performed.
使用set +m
、set +o monitor
或禁用作业控制shopt -u -o monitor
。要启用lastpipe
do shopt -s laspipe
. 如果您同时执行这两项操作,exit
则前面示例中的 将导致while
循环和包含的 shell都退出,并且echo
不会执行最终的那里。
回答by chepner
false
always returns an exit code of 1.
false
总是返回 1 的退出代码。
#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0
done
回答by chukko
Some of answers rely on rewriting the code. In some cases it might be a foreign code that you have no control over.
一些答案依赖于重写代码。在某些情况下,它可能是您无法控制的外来代码。
Although for this specific question, it is enough to set $? to 1, but if you need to set $? to any value - the only helpful answer is the one from Dennis Williamson's.
虽然对于这个特定的问题,设置 $? 到 1,但如果你需要设置 $? 任何价值 - 唯一有用的答案是丹尼斯威廉姆森的答案。
A bit more efficient approach, which does not spawn a new child (but is a also less terse), is:
一种更有效的方法,它不会产生一个新的孩子(但也不那么简洁),是:
function false() { echo "$$"; return ${1:-1}; }
false 42
Note: echo part is there just to verify it runs in the current process.
注意:echo 部分只是为了验证它在当前进程中运行。
回答by unwind
回答by Andry
Didn't find anything lighter than just a simple function:
没有找到比简单功能更轻松的东西:
function set_return() { return ${1:-0}; }
All other solutions like (...)
or [...]
or false
might contain an external process call.
所有其他解决方案,如(...)
或[...]
或false
可能包含外部进程调用。
回答by David K
Would something like this be what your looking for ?
这样的东西会是你要找的吗?
#!/bin/bash
TEMPVAR=1
while [ $TEMPVAR -eq 1 ]
do
#do something until it returns 0
#construct the logic which will cause TEMPVAR to be set 0 then check for it in the
#if statement
if [ yourcodehere ]; then
$TEMPVAR=0
fi
done
回答by don provan
Old question, but there's a much better answer:
老问题,但有一个更好的答案:
#!/bin/bash
until
#do something until it returns success
do
:;
done
If you're looping until something is successful, then just do that something in the until section. You can put exactly the same code in the until section you were thinking you had to put in the do/done section. You aren't forced to write the code in the do/done section and then transfer its results back to the while or until.
如果您一直循环直到某事成功,那么只需在直到部分执行该操作。您可以将完全相同的代码放入您认为必须放入 do/done 部分的直到部分。您不必在 do/done 部分编写代码,然后将其结果传输回 while 或 until。
回答by Steven Kearnes
You can use until
to handle cases where #do something until it returns 0
returns something other than 1 or 0:
您可以until
用来处理#do something until it returns 0
返回 1 或 0 以外的值的情况:
#!/bin/bash
false
until [ $? -eq 0 ]
do
#do something until it returns 0
done
回答by Stephen Quan
$?
can contain a byte value between 0..255. Return numbers outside this range will be remapped to this range as if a bitwise and 255 was applied.
$?
可以包含 0..255 之间的字节值。超出此范围的返回数字将重新映射到此范围,就像应用了按位和 255 一样。
exit value
- can be used to set the value, but is brutal since it will terminate a process/script.
exit value
- 可用于设置值,但很残酷,因为它会终止进程/脚本。
return value
- when used in a function is somewhat traditional.
return value
- 在函数中使用时有点传统。
[[ ... ]]
- is good for evaluating boolean expressions.
[[ ... ]]
- 适用于评估布尔表达式。
Here is an example of exit
:
下面是一个例子exit
:
# Create a subshell, but, exit it with an error code:
$( exit 34 ); echo $? # outputs: 34
Here are examples of return
:
以下是以下示例return
:
# Define a `$?` setter and test it:
set_return() { return ; }
set_return 0; echo $? # outputs: 0
set_return 123; echo $? # outputs: 123
set_return 1000; echo $? # outputs: 232
set_return -1; echo $? # outputs: 255
Here are are examples of [ ... ]
:
以下是以下示例[ ... ]
:
# Define and use a boolean test:
lessthan() { [[ < ]]; }
lessthan 3 8 && echo yes # outputs: yes
lessthan 8 3 && echo yes # outputs: nothing
Note, when using $?
as a conditional, zero (0) means success, non-zero means failure.
请注意,当$?
用作条件时,零 (0) 表示成功,非零表示失败。