如何判断system命令执行结果

1. 先来看一下system()函数的简单介绍:
1#include <stdlib.h>
2int system(const char *command);

system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.

system()函数调用/bin/sh来执行参数指定的命令,/bin/sh 一般是一个软连接,指向某个具体的shell,比如bash,-c选项是告诉shell从字符串command中读取命令;
在该command执行期间,SIGCHLD是被阻塞的,好比在说:hi,内核,这会不要给我送SIGCHLD信号,等我忙完再说;
在该command执行期间,SIGINT和SIGQUIT是被忽略的,意思是进程收到这两个信号后没有任何动作。
2.   再来看一下system()函数返回值
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2). Thus, the exit code of the command will be WEXITSTATUS(status). In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127).
If the value of command is NULL, system() returns nonzero if the shell is available, and zero if not.
为了更好的理解system()函数返回值,需要了解其执行过程,实际上system()函数执行了三步操作:
1.fork一个子进程;
2.在子进程中调用exec函数去执行command;
3.在父进程中调用wait去等待子进程结束。
返回-1的情况: 对于fork失败,system()函数返回-1。
返回其他值的情况:  如果exec执行成功,也即command顺利执行完毕,则返回command通过exit或return返回的值。
(注意,command顺利执行不代表执行成功,比如command:"rm debuglog.txt",不管文件存不存在该command都顺利执行了)
返回127的情况: 如果exec执行失败,也即command没有顺利执行,比如被信号中断,或者command命令根本不存在,system()返回127.
返回1的情况: 如果command为NULL,则system()函数返回非0值,一般为1.

3. 看一下system()函数的源码

看完这些,我想肯定有人对system()函数返回值还是不清楚,看源码最清楚,下面给出一个system()函数的实现:
01int system(const char * cmdstring)
02{
03    pid_t pid;
04    int status;
05 
06if(cmdstring == NULL)
07{
08    return (1); //如果cmdstring为空,返回非零值,一般为1
09}
10 
11if((pid = fork())<0)
12{
13    status = -1; //fork失败,返回-1
14}
15else if(pid == 0)
16{
17    execl("/bin/sh""sh""-c", cmdstring, (char *)0);
18    _exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~
19}
20else //父进程
21{
22    while(waitpid(pid, &status, 0) < 0)
23    {
24        if(errno != EINTR)
25        {
26            status = -1; //如果waitpid被信号中断,则返回-1
27            break;
28        }
29    }
30}
31 
32    return status; //如果waitpid成功,则返回子进程的返回状态
33}

仔细看完这个system()函数的简单实现,那么该函数的返回值就清晰了吧,那么什么时候system()函数返回0呢?只在command命令返回0时。
4. 看一下该怎么监控system()函数执行状态
01int status;
02if(NULL == cmdstring) //如果cmdstring为空趁早闪退吧,尽管system()函数也能处理空指针
03{
04    return XXX;
05}
06status = system(cmdstring);
07if(status < 0)
08{
09    printf("cmd: %s\t error: %s", cmdstring, strerror(errno)); // 这里务必要把errno信息输出或记入Log
10    return XXX;
11}
12 
13if(WIFEXITED(status))
14{
15    printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); //取得cmdstring执行结果
16}
17else if(WIFSIGNALED(status))
18{
19    printf("abnormal termination,signal number =%d\n", WTERMSIG(status)); //如果cmdstring被信号中断,取得信号值
20}
21else if(WIFSTOPPED(status))
22{
23    printf("process stopped, signal number =%d\n", WSTOPSIG(status)); //如果cmdstring被信号暂停执行,取得信号值
24}
5.  这里给我出的做法:

/*

* 功能:
*  判断system命令执行结果
* 参数:
*  int:system命令返回值
* 返回值:
*  bool
*/
bool Application::systemStatus(int status)
{
#ifndef WIN32
    if (-1 == status)
    {
        qDebug() << QString("system execute failed");
        return false;
    }
    else
    {
        if (WIFEXITED(status))
        {
            if (0 != WEXITSTATUS(status))
            {
                qDebug() << QString("run shell - failed;exit code:%1").arg(WEXITSTATUS(status));
                return false;
            }
        }
        else
        {
            qDebug() << QString("system - failed;exit code:%1").arg(WIFEXITED(status));
            return false;
        }
    }
#endif
    return true;
}

 number =%d\n", WSTOPSIG(status)); //如果cmdstring被信号暂停执行,取得信号值
24}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,可以通过执行操作系统命令并获取命令执行结果的多种方式,其中最简单的方法是使用`ProcessBuilder`类。 首先,我们需要创建一个`ProcessBuilder`对象,并将要执行命令作为参数传递给该对象。然后,我们可以使用`start()`方法启动命令,创建一个`Process`对象。 可以使用`Process`对象提供的方法来获取命令执行结果。其中,`getInputStream()`方法用于获取命令的输出流,`getErrorStream()`方法用于获取命令的错误流,`getOutputStream()`方法用于获取命令的输入流。 例如,如果我们要获取命令的输出结果,可以使用如下代码: ```java ProcessBuilder processBuilder = new ProcessBuilder("command"); Process process = processBuilder.start(); // 获取命令的输出流 InputStream inputStream = process.getInputStream(); Scanner scanner = new Scanner(inputStream); while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); } ``` 在上述代码中,我们使用`Scanner`类从输入流中读取命令的输出,并逐行打印出来。 同样的,我们也可以获取命令的错误流或输入流并进行相应的处理。 需要注意的是,`ProcessBuilder`类和`Process`类在Java的`java.lang.ProcessBuilder`和`java.lang.Process`包中定义,所以我们需要在代码中引入相应的包。 总结起来,通过使用`ProcessBuilder`类,Java可以方便地调用操作系统命令并获取命令执行结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值