bash:一行上有多个命令,具有不同的退出代码

bash:一行上有多个命令,具有不同的退出代码

我使用中提供的函数bash从代码运行命令。我的问题不是关于实现,而是与我的问题相关的一件事是我必须在一行上运行多个命令。c++systemcstdlibc++

例如,我运行另一个目录中包含的 gnuplot 脚本。所以我的命令如下:

cd some/path; gnuplot -e gnuplot_file.gp; cd - > /dev/NULL

cd出于个人原因,这两个命令都很重要。我还想“隐藏”输出/dev/NULL

这是我的问题:我如何知道gnuplot命令的退出状态?知道它是否失败就足够了。

我的问题是,我当前获得了最后一个命令的退出状态,即使失败也是如此gnuplot

我知道如果我使用&&而不是;,如果前一个命令失败并且退出状态将为 false,则最后一个命令将不会被执行。但我需要执行最后一个命令......

解决方法是什么?

答案1

将其放入gnuplot子 shell 中,然后它就是执行的最后一个命令。您也不再需要最后一个,cd因为子 shell 开头的目录更改仅影响gnuplot,因此重定向到/dev/null也是没有意义的。

( cd some/path; gnuplot -e gnuplot_file.gp )

也许您打算将重定向/dev/null应用于整个命令? (但这不是您在问题中所写的内容。)

( cd some/path; gnuplot -e gnuplot_file.gp ) >/dev/null

最后,我对这样的代码片段的偏好是gnuplot仅在初始cd成功时才运行。这会影响退出状态,因为你会得到失败的如果目录更改失败则返回,但可能是更安全的代码

( cd some/path && gnuplot -e gnuplot_file.gp ) >/dev/null

答案2

将返回值保存在变量中:

cd some/path; gnuplot -e gnuplot_file.gp; gnuplot_ret=$?; cd "$OLDPWD"; exit $gnuplot_ret

另一种方式:在子 shell 中运行:

(cd some/path; gnuplot -e gnuplot_file.gp)

由于目录更改发生在子 shell 中,因此不会影响您当前的 shell,并且您无需cd返回。并且您可以免费获得退出状态。

答案3

您可以在变量中捕获退出代码:

cd some/path; gnuplot -e gnuplot_file.gp ; a=$?

返回上一级目录(没有任何控制台输出):

cd -- "$OLDPWD"

打印退出代码

然后打印捕获的退出代码(整行):

cd some/path; gnuplot -e gnuplot_file.gp ; a=$?; cd -- "$OLDPWD"; echo "$a"

如果您需要重新创建退出代码,有多种可能的方法:

[ "x$a" == 'x0' ]
[ "$a" -eq 0 ]
[ ! "${a#0}" ]
[[ $a == 0 ]]
[[ $a -eq 0 ]]

建议不要使用“${a#1}”,因为错误退出代码可以是 1 以外的任何数字。不保证a错误退出代码为 1。

或者,由于 a 是一个数字,如果您接受使用算术解决方案 (bash):

(( a == 0 ))
! (( a ))
(( ! a ))

重新创建退出代码..

完整的行是:

cd some/path; gnuplot -e gnuplot_file.gp ; a=$?; cd -- "$OLDPWD"; (( ! a ))

退出代码将为 0 或 1,所有错误都将报告退出代码为 1。


完整退出代码

仅当Anexit "$a"有助于结束脚本的执行时才有用。
了解这将保留实际的退出代码。

 cd some/path && gnuplot -e gnuplot_file.gp ; a=$?; cd -- "$OLDPWD"; exit "$a"

如果在函数内部使用“return "$a"”可能会很有用。

function_gnuplot(){
    cd some/path && gnuplot -e gnuplot_file.gp ; a=$?
    cd -- "$OLDPWD"; return "$a"
}

答案4

您可以在调用之前更改代码中的目录system

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define BUFFSIZE 1024

int main(int argc, char **argv) {
  char old_dir[BUFFSIZE];
  getcwd(old_dir, BUFFSIZE); 

  chdir("some/path");

  int retvalue=system("gnuplot -e gnuplot_file.gp");

  chdir(old_dir);

  if (retvalue == -4) {
    /* do something ... */
  }
}

请注意,该解决方案是不是线程安全的因为更改了进程的当前目录。

相关内容