![bash:一行上有多个命令,具有不同的退出代码](https://linux22.com/image/82904/bash%EF%BC%9A%E4%B8%80%E8%A1%8C%E4%B8%8A%E6%9C%89%E5%A4%9A%E4%B8%AA%E5%91%BD%E4%BB%A4%EF%BC%8C%E5%85%B7%E6%9C%89%E4%B8%8D%E5%90%8C%E7%9A%84%E9%80%80%E5%87%BA%E4%BB%A3%E7%A0%81.png)
我使用中提供的函数bash
从代码运行命令。我的问题不是关于实现,而是与我的问题相关的一件事是我必须在一行上运行多个命令。c++
system
cstdlib
c++
例如,我运行另一个目录中包含的 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 ... */
}
}
请注意,该解决方案是不是线程安全的因为更改了进程的当前目录。