system() 执行 shell 命令


实现原理

strace 跟踪结果:

clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7fff936fc388) = 15661
wait4(15661, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 15661
实际的过程:

1. 父进程 - clone() 一个子进程

2. 父进程 - wait4() 子进程退出(如果 SIGCHLD 处理方式为 SIG_DFL, 则阻塞等待指子进程退出;如果是 SIG_IGN, 则立马返回 -1

3. 子进程 - execl(/bin/sh -c command)


返回值

返回值可能的情况:

-1: system() 执行失败,例如 clone() 失败、wait4() 失败(SIG_IGN 时返回 -1)

>=0: system() 执行成功,命令执行成功或失败,通过 WEXITSTATUS() 获取命令执行的返回码


正确的使用方法

1. 处理 SIGCHLD 信号

2. WIFEXITED() 和 WEXITSTATUS()

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
    char cmd[] = "su www -c 'kdir -p -m 755 /data/inst-123456 &>/dev/null '";
    sighandler_t old_sighandler = signal(SIGCHLD, SIG_DFL);
    int rv = system(cmd);
    signal(SIGCHLD, old_sighandler);
    if (-1 == rv)
    {
        std::cout << "error: " << strerror(errno) << std::endl;
        return -1;
    }
    
    std::cout << "return value: " << rv << std::endl;
    
    if (WIFEXITED(rv))
    {
        std::cout << "subprocess exited, exit code: " << WEXITSTATUS(rv) << std::endl;
        if (0 == WEXITSTATUS(rv))
        {
            // if command returning 0 means succeed
            std::cout << "command succeed" << std::endl;
        }
        else
        {
            if(127 == WEXITSTATUS(rv))
            {
                std::cout << "command not found" << std::endl;
                return WEXITSTATUS(rv);
            }
            else
            {
                std::cout << "command failed: " << strerror(WEXITSTATUS(rv)) << std::endl;
                return WEXITSTATUS(rv);
            }
        }
    }
    else
    {
        std::cout << "subprocess exit failed" << std::endl;
        return -1;
    }
    
    return 0;
}


命令后台执行

如果想命令在后台执行,可以在命令后面加 "&", 但是这样做的后果是:只要 system() 执行成功,不管命令是否存在、命令执行是否成功,返回值都为 0.



popen

http://blog.csdn.net/duyiwuer2009/article/details/50688493




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值