system_ex():增强版本的system()
在Linux上,如果一个程序中需要执行shell 命令,可以有以下几种方法:
system(): 执行一个shell命令,返回该命令执行后的返回值popen():执行一个shell命令,从返回的文件描述符中读出命令执行后输出的内容自己写fork(), dup2(), execl, wait4,通过execl中执行“/bin/sh -c <cmd>"来得到执行结果system()只能得到命令执行返回值,得不到输出的结果。popen()正好相反。
下面的system_ex()可以兼而有之,它是通过第三种方法来执行shell命令。
int system_ex(char* cmd, char* output, int size){ int fd[2]; pid_t pid; int n, count; int wait_val = 0; if(cmd == NULL){ return -1; } /* no need to save output, use original system() */ if(output == NULL || size <= 0){ return system(cmd); } if (pipe(fd) < 0){ return -1; } if ((pid = fork()) < 0){ close(fd[0]); close(fd[1]); return -1; } else if (pid > 0){//parent close(fd[1]);//close write pipe count = 0; while (count < size){ n = read(fd[0], output + count, size-count); if(n <= 0){ break; } count += n; } output[size - 1] = '\0'; /*terminate the string */ close(fd[0]); if (wait4(pid, &wait_val, 0, 0) == -1){ wait_val = -1; } return wait_val; }else{//child close(fd[0]);//close read pipe if (fd[1] != STDOUT_FILENO){ dup2(fd[1], STDOUT_FILENO); close(fd[1]); } execl("/bin/sh", "sh", "-c", cmd, (char*)0); //should not reach here, otherwise execl failed /* SUSv3 mandates an exit code of 127 for the child if the * command interpreter can not be invoked. */ _exit(127); } //should not reach here return -1;}