如何设置$?还是Bash中的返回代码?
我想设置一次返回值,使其进入while循环:如何设置$?还是Bash中的返回代码?,bash,error-handling,return-value,exit-code,Bash,Error Handling,Return Value,Exit Code,我想设置一次返回值,使其进入while循环: #!/bin/bash while [ $? -eq 1 ] do #do something until it returns 0 done 为了使其工作,我需要设置$?=1开始时,但这不起作用。我认为,在进入while循环之前,可以通过运行一个保证失败的命令隐式地执行此操作 #!/bin/bash RC=1 while [ $RC -eq 1 ] do #do something until it returns 0
#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0
done
为了使其工作,我需要设置
$?=1开始时,但这不起作用。我认为,在进入while
循环之前,可以通过运行一个保证失败的命令隐式地执行此操作
#!/bin/bash
RC=1
while [ $RC -eq 1 ]
do
#do something until it returns 0
RC=$?
done
当然,这种规范的命令是,
您想要的是这样的东西吗
#!/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
false
始终返回退出代码1
#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0
done
通过在子shell中使用参数执行exit
,可以设置任意退出代码
$ (exit 42); echo "$?"
42
所以你可以做:
(exit 1) # or some other value > 0 or use false as others have suggested
while (($?))
do
# do something until it returns 0
done
或者你可以:
这两种方法都保证循环至少运行一次,我相信这就是您的目标
为完整起见,exit
和return
都接受一个可选参数,该参数是一个整数(正、负或零),它将返回代码设置为除256后整数的余数。使用exit
退出当前shell(或脚本或子shell*),使用return
退出函数
示例:
$ (exit -2); echo "$?"
254
$ foo () { return 2000; }; foo; echo $?
208
*即使对于由管道创建的子shell也是如此(除非同时禁用作业控制和启用了lastpipe
):
请注意,最好使用break
来保留循环,但它的参数是要中断的循环的级别数,而不是返回代码
使用set+m
,set+o监视器
或shopt-u-o监视器
禁用作业控制。要启用lastpipe
doshopt-s laspipe
。如果你同时做这两件事,上例中的exit
将导致while
循环和包含的shell同时退出,并且不会执行最终的回显。您可以使用until
处理直到返回0为止的情况
#!/bin/bash
false
until [ $? -eq 0 ]
do
#do something until it returns 0
done
有些答案依赖于重写代码。在某些情况下,它可能是您无法控制的外来代码
虽然对于这个特定的问题,设置$就足够了?设置为1,但如果需要设置$?对任何价值来说,唯一有用的答案是丹尼斯·威廉姆森的答案
一种更有效的方法,它不会产生新的子代(但也不那么简洁),是:
注意:echo部分只是为了验证它是否在当前进程中运行。旧问题,但有一个更好的答案:
#!/bin/bash
until
#do something until it returns success
do
:;
done
如果你在循环直到某件事成功,那么就在“直到”部分中做这件事。您可以将完全相同的代码放在您认为必须放在do/done部分的until部分中。您不必在do/done部分编写代码,然后将其结果传输回while或until。没有发现比简单函数更简单的功能:
function set_return() { return ${1:-0}; }
所有其他解决方案,如(…)
或[…]
或false
可能包含外部进程调用。$?
可以包含0到255之间的字节值。超出此范围的返回数将重新映射到此范围,就像应用了按位and 255一样
退出值
-可用于设置该值,但由于它将终止进程/脚本,因此非常残忍
返回值
-在函数中使用时有点传统
[[…]]
-适用于计算布尔表达式
下面是退出的一个示例:
# Create a subshell, but, exit it with an error code:
$( exit 34 ); echo $? # outputs: 34
下面是返回的示例:
# Define a `$?` setter and test it:
set_return() { return $1; }
set_return 0; echo $? # outputs: 0
set_return 123; echo $? # outputs: 123
set_return 1000; echo $? # outputs: 232
set_return -1; echo $? # outputs: 255
以下是[…]
的示例:
# Define and use a boolean test:
lessthan() { [[ $1 < $2 ]]; }
lessthan 3 8 && echo yes # outputs: yes
lessthan 8 3 && echo yes # outputs: nothing
定义并使用布尔测试:
lessthan(){[$1<$2]];}
lessthan 3 8&&echo是#输出:是
lessthan 8 3&&echo yes#输出:无
注意,当使用$?
作为条件时,零(0)表示成功,非零表示失败。应为$(退出42);echo“$?”
@ElliotChance:我答案中的美元符号表示提示,并按原样工作。您的建议也可以,但不是必需的。请注意,您可以使用范围0-255,但实际情况是256的模。这意味着您可以退出300和$?将是44
。而且,exit-1
将返回255
(我经常看到一个奇怪的习惯)。只是一些需要注意的事情。最好只返回您想要的值,因此坚持0-255,这样您(或其他人)就不会感到惊讶。@Boweb-1 mod X==X-1
是很正常的,您基本上会继续将0,1,…,X-1
序列变成负数。有关变体和基本原理,请参见。@toolforger--是的。。。这就是我上面说的。我对数学不感到困惑。我不明白为什么开发人员会想用一种复杂的方法来达到255。我的最佳猜测是,该约定意味着255返回代码没有意义(并且将其编写为-1
稍微容易一些(?)。RC 1对于泛型/未指定的错误是常见的,但我从未见过任何实际评估255(特别是)的$?
。虽然我会避免调用此函数false
(这可能会让读者感到困惑),但使用函数要比使用子shell快得多。一个粗糙的微基准表明,有一个次壳层的开销超过100倍。为什么让人困惑?与传统的false命令相同,只是有所改进,因为它允许您设置首选错误值/因为false 2
将根据您的函数是否在环境中而具有不同的行为。false的所有标准调用者仍将工作(因为false只应返回非零)。唯一真正令人困惑的是将其称为false 0(这可能会抛出一个错误以避免混淆)。所以它不会破坏任何东西——它只会提供额外的价值。如果有人感到困惑,他们可以很容易地使用自己的名字(并打破这个习惯)
# Create a subshell, but, exit it with an error code:
$( exit 34 ); echo $? # outputs: 34
# Define a `$?` setter and test it:
set_return() { return $1; }
set_return 0; echo $? # outputs: 0
set_return 123; echo $? # outputs: 123
set_return 1000; echo $? # outputs: 232
set_return -1; echo $? # outputs: 255
# Define and use a boolean test:
lessthan() { [[ $1 < $2 ]]; }
lessthan 3 8 && echo yes # outputs: yes
lessthan 8 3 && echo yes # outputs: nothing