曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入。只是简单的知道用这个函数执行一个系统命令,这远远不够,它的返回值、它所执行命令的返回值以及命令执行失败原因如何定位,这才是重点。当初因为这个函数风险较多,故抛弃不用,改用其他的方法。这里先不说我用了什么方法,这里必须要搞懂system()函数,因为还是有很多人用了system()函数,有时你不得不面对它。
 
先来看一下system()函数的简单介绍:
system()函数调用/bin/sh来执行参数指定的命令,/bin/sh 一般是一个软连接,指向某个具体的shell,比如bash,-c选项是告诉shell从字符串command中读取命令;
在该command执行期间,SIGCHLD是被阻塞的,好比在说:hi,内核,这会不要给我送SIGCHLD信号,等我忙完再说;
在该command执行期间,SIGINT和SIGQUIT是被忽略的,意思是进程收到这两个信号后没有任何动作。
 
再来看一下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去等待子进程结束。
对于fork失败,system()函数返回-1。
如果exec执行成功,也即command顺利执行完毕,则返回command通过exit或return返回的值。
(注意,command顺利执行不代表执行成功,比如command:"rm debuglog.txt",不管文件存不存在该command都顺利执行了)
如果exec执行失败,也即command没有顺利执行,比如被信号中断,或者command命令根本不存在,system()函数返回127.
如果command为NULL,则system()函数返回非0值,一般为1.
 
看一下system()函数的源码
看完这些,我想肯定有人对system()函数返回值还是不清楚,看源码最清楚,下面给出一个system()函数的实现:
 
看一下该怎么监控system()函数执行状态
这里给我出的做法:

system()函数用起来很容易出错,返回值太多,而且返回值很容易跟command的返回值混淆。这里推荐使用popen()函数替代,关于popen()函数的简单使用也可以通过上面的链接查看。

popen()函数较于system()函数的优势在于使用简单,popen()函数只返回两个值:
成功返回子进程的status,使用WIFEXITED相关宏就可以取得command的返回结果;
失败返回-1,我们可以使用perro()函数或strerror()函数得到有用的错误信息。

这篇文章只涉及了system()函数的简单使用,还没有谈及SIGCHLD、SIGINT和SIGQUIT对system()函数的影响,事实上,之所以今天写这篇文章,是因为项目中因有人使用了system()函数而造成了很严重的事故。现像是system()函数执行时会产生一个错误:“No child processes”。

关于这个错误的分析,感兴趣的朋友可以看一下:http://my.oschina.net/renhc/blog/54582

(转)Linux下使用system()函数一定要谨慎的更多相关文章

  1. 【C/C++】Linux下使用system()函数一定要谨慎

    [C/C++]Linux下使用system()函数一定要谨慎 http://my.oschina.net/renhc/blog/53580 曾经的曾经,被system()函数折磨过,之所以这样,是因为 ...

  2. Linux下使用system()函数一定要谨慎

    转载自:http://my.oschina.net/renhc/blog/53580   linux尽量避免使用system. 曾经的曾经,被system()函数折磨过,之所以这样,是因为对syste ...

  3. [转]【C/C++】Linux下使用system()函数一定要谨慎

    曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入.只是简单的知道用这个函数执行一个系统命令,这远远不够,它的返回值.它所执行命令的返回值以及命令执行失败原 ...

  4. 关于linux中的system函数

    Linux下使用system()函数一定要谨慎 https://blog.csdn.net/senen_wakk/article/details/51496322 system()正确应用 https ...

  5. linux下代替system的基于管道的popen和pclose函数

    linux下使用system需要谨慎,那么代替它的方法是什么呢? 标准I/O函数库提供了popen函数,它启动另外一个进程去执行一个shell命令行. 这里我们称调用popen的进程为父进程,由pop ...

  6. 【转】在嵌入式Linux和PC机Linux下使用popen函数时,程序运行结果有差异。

    下面程序演示了在嵌入式Linux和PC机Linux下使用popen函数时,程序的运行结果是有差异的. 两个程序 atest.c 和 btest.c,atest 检查是否有 btest 进程运行,如果没 ...

  7. Linux下利用ioctl函数获取网卡信息

    linux下的ioctl函数原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv ...

  8. Linux下系统时间函数、DST等相关问题总结(转)

    Linux下系统时间函数.DST等相关问题总结 下面这个结构体存储了跟时区相关的位移量(offset)以及是否存在DST等信息,根据所在的时区信息,很容易找到系统时间与UTC时间之间的时区偏移,另外根 ...

  9. 【转】Linux下(C/C++)使用system()函数一定要谨慎

    转自:http://my.oschina.net/renhc/blog/53580   曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入.只是简单的知道用 ...

随机推荐

  1. Android动画效果 translate、scale、alpha、rotate 切换Activity动画 控件位置调整

    2011.10.28注:如果需要控件停在动画后的位置,需要设置android:fillAfter属性为true,在set节点中.默认在动画结束后回到动画前位置.设置android:fillAfter后 ...

  2. Android学习拾遗

    1. java中的flush()作用:强制将输出流缓冲区的数据送出. 2. 文件存储: 存储到内部:另外使用一个class实现,最开始初始化用了this,后来放在这里不合适,改成了带参数的构造方法. ...

  3. mysql5.6配置-my

    # mkdir -p /home/mysql/3306/{data,binlog,logs} [client] port = socket=/tmp/my3306.sock [mysql] no-au ...

  4. Linux虚拟机网络连接的三种方式

    Bridge桥接模式.NAT模式.Host-only仅主机模式: 桥接模式:虚拟机使用真实网卡进行通信,配置简单:只要和真实计算机在同一个网段内,就可以直接通信:局域网内如果有其他计算机,也可以进行访 ...

  5. Java学习之抽象类

    抽象类特点: 1.抽象方法必须定义在抽象类中2.abstract关键字修饰:只能修饰类和方法3.抽象类不能实例化4.抽象类中的方法要被使用,必须由子类重写所有的抽象方法,实例化其子类 如果子类只重写部 ...

  6. 查看mysql慢日志,进行优化

    MySQL 慢查询的相关参数解释:slow_query_log :是否开启慢查询日志,1表示开启,0表示关闭. slow_query_log    :是否开启慢查询日志,1表示开启,0表示关闭. lo ...

  7. 【C++第一个Demo】---控制台RPG游戏1【游戏简介】

       经过1个月的制作和多次修改,终于有了基本雏形(此篇仅用于纪念历时3个多月C/C++学习所付出努力,也给和我一样苦恼于不能快速理解面向对象的同学们一点灵感) 在制作这个Demo过程中也受到了很多大 ...

  8. C# 线程池的使用 终止线程池中的队列

    C#的线程池使用起来还是非常简单的,这里记录一下. 根据http://blog.csdn.net/chen_zw/article/details/7939834里的描述这里记录一下C#线程池的特点 一 ...

  9. 【总】IdentityServer4 32篇汇总

    随笔分类 - IdentityServer4 IdentityServer4 常见问题 - 用户拒绝授权后报错 摘要: 1.问题说明 在 IdentityServer4 Web 授权中,一般会有一个显 ...

  10. OI中的快速傅里叶变换(FFT)

    快速傅里叶变换(FFT)                                                                               ---- LLpp ...