在bash中,如何设置返回码?

Joh*_*mBF 29 error-handling bash return-value exit-code

我想设置一次返回值,使其进入while循环:

#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0    
done
Run Code Online (Sandbox Code Playgroud)

为了使这个工作,我需要$? = 1在开始时设置,但这不起作用.

Pau*_*ce. 111

您可以通过exit在子shell中执行参数来设置任意退出代码.

$ (exit 42); echo "$?"
42
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做:

(exit 1)    # or some other value > 0 or use false as others have suggested
while (($?))
do
    # do something until it returns 0    
done
Run Code Online (Sandbox Code Playgroud)

或者你可以模拟一个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
Run Code Online (Sandbox Code Playgroud)

其中任何一个都保证循环至少运行一次,我认为这是你的目标.

为了完整性,exit并且return每个接受其通过256.当前壳(或脚本或子外壳*)设置返回代码作为分割后的整数的剩余部分的可选参数,它是一个整数(正,负或零),使用退出exit并使用退出函数return.

例子:

$ (exit -2); echo "$?"
254
$ foo () { return 2000; }; foo; echo $?
208
Run Code Online (Sandbox Code Playgroud)

*即使对于由管道创建的子壳也是如此(除非禁用并lastpipe启用了作业控制):

$ echo foo | while read -r s; do echo "$s"; exit 333; done; echo "$?"
77
Run Code Online (Sandbox Code Playgroud)

请注意,最好使用break离开循环,但其参数是针对循环的级别数而不是返回代码.

作业控制是使用禁用set +m,set +o monitorshopt -u -o monitor.要启用lastpipedo shopt -s laspipe.如果你同时执行这两个操作,exit前面的例子中将导致while循环包含shell 退出,最后echo将不会执行.

  • @ElliotChance:我的答案中的美元符号表示提示并按原样工作.你提出的建议也有用,但没有必要. (3认同)

che*_*ner 18

false 始终返回退出代码1.

#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0    
done
Run Code Online (Sandbox Code Playgroud)


Eug*_*eck 11

#!/bin/bash

RC=1

while [ $RC -eq 1 ]
do

  #do something until it returns 0    

  RC=$?
done
Run Code Online (Sandbox Code Playgroud)


chu*_*kko 6

一些答案依赖于重写代码.在某些情况下,它可能是您无法控制的外国代码.

虽然对于这个具体问题,设置$就足够了?到1,但如果你需要设置$?任何价值 - 唯一有用的答案是丹尼斯威廉姆森的答案.

一种更有效的方法,它不会产生一个新的孩子(但也是一个不那么简洁),是:

function false() { echo "$$"; return ${1:-1}; }
false 42
Run Code Online (Sandbox Code Playgroud)

注意:echo部分只是为了验证它在当前进程中运行.


And*_*dry 6

没有找到比简单功能更轻的东西:

function set_return() { return ${1:-0}; }
Run Code Online (Sandbox Code Playgroud)

所有其他解决方案(如(...)[...]false可能包含外部进程调用。


unw*_*ind 5

我认为您可以通过在进入循环之前运行保证失败的命令来隐式地执行此操作while

当然,规范的此类命令是false.