1. 先来看一下system()函数的简单介绍:
2 | int 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()函数的实现:
01 | int system ( const char * cmdstring) |
17 | execl( "/bin/sh" , "sh" , "-c" , cmdstring, ( char *)0); |
22 | while (waitpid(pid, &status, 0) < 0) |
仔细看完这个system()函数的简单实现,那么该函数的返回值就清晰了吧,那么什么时候system()函数返回0呢?只在command命令返回0时。
4.
看一下该怎么监控system()函数执行状态
06 | status = system (cmdstring); |
09 | printf ( "cmd: %s\t error: %s" , cmdstring, strerror ( errno )); |
15 | printf ( "normal termination, exit status = %d\n" , WEXITSTATUS(status)); |
17 | else if (WIFSIGNALED(status)) |
19 | printf ( "abnormal termination,signal number =%d\n" , WTERMSIG(status)); |
21 | else if (WIFSTOPPED(status)) |
23 | printf ( "process stopped, signal number =%d\n" , WSTOPSIG(status)); |
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)); |