在bash / ksh中获取命令的退出代码

我想写这样的代码:

command="some command" safeRunCommand $command safeRunCommand() { cmnd=$1 $($cmnd) if [ $? != 0 ]; then printf "Error when executing command: '$command'" exit $ERROR_CODE fi } 

但是这个代码不能按我想要的方式工作。 我犯了什么错误?

以下是固定代码:

 #!/bin/ksh safeRunCommand() { typeset cmnd="$*" typeset ret_code echo cmnd=$cmnd eval $cmnd ret_code=$? if [ $ret_code != 0 ]; then printf "Error : [%d] when executing command: '$cmnd'" $ret_code exit $ret_code fi } command="ls -l | grep p" safeRunCommand "$command" 

现在,如果你看看这个代码,我改变了一些东西:

  • 使用typeset不是必要的,但是一个好的做法。 它使cmndret_codesafeRunCommand本地
  • 使用ret_code是没有必要的,但是将返回代码存储在某个variables(尽快存储)是一个很好的习惯,以便稍后可以像在printf "Error : [%d] when executing command: '$command'" $ret_code一样使用它printf "Error : [%d] when executing command: '$command'" $ret_code
  • 传递命令周围的命令,如safeRunCommand "$command" 。 如果你不那么cmnd只会得到值ls而不是ls -l 。 如果你的命令包含pipe道,则更为重要。
  • 如果要保留空格,可以使用typeset cmnd="$*"而不是typeset cmnd="$1" 。 你可以尝试两者取决于你的命令参数有多复杂。
  • eval用于评估,以便包含pipe道的命令可以正常工作

注意:尽pipe没有像grep这样的错误,记得有些命令给出1作为返回码。 如果grep发现了东西,它会返回0否则1。

我曾经用KSH / BASH进行过testing。 它工作正常。 让我知道如果你遇到问题运行这个。

尝试

 safeRunCommand() { "$@" if [ $? != 0 ]; then printf "Error when executing command: '$1'" exit $ERROR_CODE fi } 

它应该是$cmd而不是$($cmd) 。 在我的包装盒上正常工作。

编辑:您的脚本只适用于单字命令,如ls。 它不适用于“ls cpp”。 为此,replacecmd="$1"; $cmd cmd="$1"; $cmd"$@" 。 而且,不要将脚本作为command="some cmd"; safeRun command运行command="some cmd"; safeRun command command="some cmd"; safeRun command ,运行它作为safeRun some cmd

另外,当你必须debugging你的bash脚本时,用'-x'标志执行。 [bash -x s.sh]。

你的脚本有几个错误。

函数(子例程)应该在尝试调用它们之前声明。 您可能想要从子程序中返回()而不是exit(),以允许调用块testing特定命令的成功或失败。 除此之外,您不会捕获“ERROR_CODE”,因此始终为零(未定义)。

用大括号包围variables引用也是很好的做法。 您的代码可能如下所示:

 #!/bin/sh command="/bin/date -u" #...Example Only safeRunCommand() { cmnd="$@" #...insure whitespace passed and preserved $cmnd ERROR_CODE=$? #...so we have it for the command we want if [ ${ERROR_CODE} != 0 ]; then printf "Error when executing command: '${command}'\n" exit ${ERROR_CODE} #...consider 'return()' here fi } safeRunCommand $command command="cp" safeRunCommand $command 

正常的想法是运行命令,然后使用$? 得到退出代码。 但是,有时您有多个需要获取退出代码的情况。 例如,您可能需要隐藏它的输出,但仍然返回退出代码,或打印退出代码和输出。

 ec() { [[ "$1" == "-h" ]] && { shift && eval $* > /dev/null 2>&1; ec=$?; echo $ec; } || eval $*; ec=$?; } 

这将使您可以select禁止输出您想要退出代码的命令。 当输出被禁止时,退出代码将直接由函数返回。

我个人喜欢把这个函数放在我的.bashrc文件中

下面我将演示几种可以使用的方法:


 # In this example, the output for the command will be # normally displayed, and the exit code will be stored # in the variable $ec. $ ec echo test test $ echo $ec 0 

 # In this example, the exit code is output # and the output of the command passed # to the `ec` function is suppressed. $ echo "Exit Code: $(ec -h echo test)" Exit Code: 0 

 # In this example, the output of the command # passed to the `ec` function is suppressed # and the exit code is stored in `$ec` $ ec -h echo test $ echo $ec 0 

使用此function解决您的代码

 #!/bin/bash if [[ "$(ec -h 'ls -l | grep p')" != "0" ]]; then echo "Error when executing command: 'grep p' [$ec]" exit $ec; fi 

您还应该注意,您将看到的退出代码将用于正在运行的grep命令,因为它是正在执行的最后一个命令。 不是ls