立即返回特定返回码的Unix命令?


28

是否有标准的Unix命令,其执行的操作与以下示例相似

$ <cmd here> 56
$ echo Return code was $?
Return code was 56
$

<cmd here>应该是可以分叉执行的东西,当进程退出时将56作为退出代码。在exitreturnshell内建不适合我要找的,因为它们影响调用shell本身它退出了。<some cmd>应该是我可以在非shell上下文中执行的东西-例如,使用调用Python脚本subprocess

例如,/usr/bin/false总是立即返回返回码1,但是我想精确控制返回码是什么。我可以通过编写自己的包装脚本来达到相同的结果

$ cat my-wrapper-script.sh # i.e., <some cmd> = ./my-wrapper-script.sh
#!/usr/bin/bash
exit $1
$ ./my-wrapper-script.sh 56
$ echo $?
56

但是我希望这里确实存在可以为我做的标准Unix命令。


10
exit是我唯一想到的一个,但是它往往会终止您的shell。 bash -c 'exit 56'bash -c "exit $1"可能为您工作。
肯尼迪

12
怎么(exit 56)
cuonglm '16

6
这听起来真的像是XYProblem:这的最终目标是什么?为什么需要一个命令,将返回的数字作为退出代码返回?
奥利维尔·杜拉克

1
好吧,如果您需要返回0或1 ,则具有truefalse内置
函数。– gardenhead

1
相关:(非便携式)返回编译时固定值的最小程序:muppetlabs.com/~breadbox/software/tiny/teensy.html
Florian Castellane

Answers:


39
  1. 一个return基于函数的函数将起作用,并且避免了打开和关闭另一个shell的需要(根据Tim Kennedy的注释):

    freturn() { return "$1" ; } 
    freturn 56 ; echo $?

    输出:

    56
  2. 使用exit在子shell:

    (exit 56)

    如果使用非的shell ksh93,则意味着要进行额外的处理,因此效率不如上面所述。

  3. bash/ zsh/ ksh93只招:

    . <( echo return 56 )

    (这也意味着一个额外的过程(以及带有管道的IPC))。

  4. zsh的lambda函数:

    (){return 56}

好主意 不幸的是,我最初的问题定义得不够好-需要“打开和关闭另一个外壳”几乎是我想要做的一项要求。我编辑了我的问题,以要求这<some cmd>是可以执行execve()的事情。
克里斯(Chris)

2
@Chris:对于任何shell命令,您都可以通过将其转换为/bin/sh -c ...originalcommand...
psmears,

3
我对?= 56不起作用感到非常失望。
约书亚

@约书亚:也许是吗?但随后这种影响成功了,您有$?设置为0 ...;)
奥利维尔·杜拉克

@OlivierDulac:不会。它吐出一个解析错误。
约书亚

17

没有标准的UNIX命令只能返回特定值。GNU的核心Utilies提供truefalse唯一的。

但是,您可以轻松地自己实现为ret

#include <stdlib.h>
int main(int argc, char *argv[]) {
  return argc > 1 ? atoi(argv[1]) : 0;
}

编译:

cc ret.c -o ret

并运行:

./ret 56 ; echo $?

印刷品:

56

如果您需要它在任何地方都能工作(可以使用bash),而无需安装任何额外的工具,则可能需要使用以下命令,如@TimKennedy在注释中建议的那样:

bash -c 'exit 56'

请注意,返回值有效范围是0..255(含)


1
truefalse不仅在GNU中,而且在Unix(甚至POSIX)中也是如此。
斯特凡Chazelas

@StéphaneChazelas感谢您指出这一点。正如OP提到的bash一样,我以某种方式假定使用GNU -即使问题本身指出“ Unix”。
tmh

14

如果需要通过执行的命令设置退出状态。该命令没有专用的命令1,但是您可以使用任何能够以任意退出状态退出的语言的解释器。sh最明显的是:

sh -c 'exit 56'

在大多数sh实现中,这仅限于退出代码0到255(sh将接受更大的值,但可能会截断它,甚至导致信号被发送到执行该过程的过程,sh如代码257到320的ksh93一样)。

退出代码可以是任何整数(int)值,但请注意,您需要使用waitid()接口来检索它,因此该值不会被截断为8位(在Linux上,它也同样会被截断waitid())。因此,为什么很少(而不是一个好主意)使用超过255的退出代码(正常操作使用0-123)。

或者:

awk 'BEGIN{exit 56}'
perl -e 'exit 56'
python -c 'exit(56)'
expect -c 'exit 56'

(不要将退出代码截断为8位)。

使用NetBSD find,您可以执行以下操作:

find / -exit 56

1exit是执行此操作的标准命令,但它是shell 专用的内置程序,不需要像常规内置程序那样在文件系统中也有该名称的命令,并且大多数系统不会包含一个


3
/* Public domain, http://creativecommons.org/publicdomain/zero/1.0/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char **argv) {
    if(!strcasecmp(argv[0],"true")) return 0;
    else if (!strcasecmp(argv[0],"false")) return 1;
    else if(argc<2) {fputs("One argument required\n",stderr);return 1;}
    else if(!strcasecmp(argv[argc-1],"true")) return 0;
    else if(!strcasecmp(argv[argc-1],"false")) return 1;
    else return atoi(argv[argc-1]);
}

将其保存在名为returncode.c和的文件中gcc -o returncode returncode.c


在一个半相关的注意事项:1)将CC0许可证不点名自己作为一个affirmer可能不是一个好主意,你应该做这样的,2)程序这个小太琐碎了您的版权的事,所以你不妨放弃许可证。
Rhymoid

2
(1)我不明白您为什么使用argv[argc-1]而不是argv[1],以及为什么不抱怨if argc>2。(2)我倾向于在argv[1]测试前进行argv[0]测试,允许用户说true 56false 56代替returncode 56。如果argv[0]是一个单词,您不会给出任何信息,argc>0这可能会造成混淆。(3)我痴迷于用户友好性,因此我会使用strcasecmp而不是strcmp。(4)我倾向于验证参数,而不使用atoi未经验证的返回值。对于这样的2美分程序,我想没关系。
G-Man说'恢复莫妮卡'

@ G-曼既不true也不false处理在Linux系统中任何参数
ThePiercingPrince

好的,没错-他们不处理任何参数,包括argv[0]; 程序/bin/true/bin/false不同的可执行文件,通过硬编码的退出代码。您已经编写了一个可以同时 true和和false(链接)安装的程序,它很聪明。但问题是如何获得用户指定的退出状态。您的程序会回答该问题,但前提是该程序安装在其他文件名下。argv无论如何,只要您正在看,我相信按照我建议的方式进行操作可以避免第三条链接,从而保持了聪明的水平。
G-Man说'Resstate Monica''Oct

0

我不确定exit命令的唯一问题是否是它退出了当前shell,但是如果是这样,则子shell可能会起作用。

username@host$ $(exit 42)
username@host$ echo $?
42

我刚刚在Cygwin Bash上进行了测试,它对我有用。

编辑:对不起,我错过了在shell上下文之外运行它的部分。在这种情况下,如果不将其包装在.sh脚本中并从您的环境中执行,将无济于事。


4
$(exit 42)试图将输出exit 42作为简单的命令执行,这没有什么意义(也无法使用yash)。(exit 42)(也可以exit在subshel​​l中运行,但不理会其输出)会更有意义,并且更便于移植(甚至是csh或Bourne shell)。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.