popen和system问题

1. 问题描述

C的代码里面去调用命令启动一个shell脚本,分别使用了下面两个途径。

其中一个是: func1(cmd) { popen(cmd,type); pclose(); }
另一个是: func2() { system(cmd); } 其中cmd类似于“./xxx.sh &”。
问题就是,func1这种调法,会导致xxx.sh运行阻塞,脚本最开始添加打印信息都没有显示,但是top后显示进程存在;而func2调用后脚本运行正常。

2. 问题分析

通过分析popen,pclose,system的源码,两者的流程分别如下:

首先看popen,pclose的流程:
父进程调用popen,
popen(cmd, type)
{ 返回一对fd(分别用来重定向子进程的读和写,但不是同时,根据type父进程和子进程最后分别只能用一个)
fork
1. 子进程重定向fd,将标准输出或者标准输入定向到一个fd,然后执行execl cmd,
返回;
2. 父进程收到子进程返回的fd
}
父进程调用pclose
pclose { 1.等待popen出来的子进程结束; 2.关闭fd }
 
然后是system的流程:
system { fork; 1. 子进程execv cmd; 2. 父进程wait子进程退出; 返回; }
 
 
上面的流程简单点,总结出来就是摘自stackoverflow上的一个解释:
popen gives you a pair of file handles you can use to read and write input and output to and from stdin/stdout of the running process in an interactive manner. The system call is merely executing that and redirecting stdin of the current process to that of the invoked child process, and stdout of that process to stdout of the current (host) process. It depends what you are trying to achieve, in general. If your goal is simply to run a command, system works fine. If you're interested in reading its output in a programmatic manner and processing it (and possibly generating more input), then popen is going to work better.

子进程的标准输入和标准输出,和跟着开启他的父进程的配置来的,当执行一个命令会后台运行的时候,比如./test.sh &, 其实又是fork出来一个子进程,然而内部封装的接口my_system接口中是连续调用的popen和pclose,这就导致了最终后台运行起来的那个test.sh子进程,它里面被popen中重定向的fd已经被关闭了,所以后面所有的echo打印都会报错“broken pipe”。表现出来就是在串口中看不到任何脚本里面的打印信息。

3. 问题总结

封装一个popen和pclose连续调用的接口,对于执行不依赖任何标准输入输出的命令是可以使用的,但是实际上这样做还不如直接调用system; 代码中频繁调用system和popen这种系统调用都会有一个问题,就是进程的切换都会带来性能上的一些开销,这个是c和shell混合编程的一个隐患,所以项目后期还是需要尽量将shell脚本中的业务集成进来,减少这种性能开销,也减少这种类似的调用上的一些异常。

popen和system问题的更多相关文章

  1. linux popen()与system()的区别

    linux popen()与system()的区别 popen() 可以在调用程序和POSIX shell /usr/bin/sh 要执行的命令之间创建一个管道(请参阅sh-posix(1) ). p ...

  2. python调用系统命令popen、system

    python调用Shell脚本,有两种方法:os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容.所以说一般我们认为popen ...

  3. 【转载】在LoadRunner中执行命令行程序之:popen()取代system()

    我想大家应该都知道在LoadRunner可以使用函数system()来调用系统指令,结果同在批处理里执行一样. 但是system()有个缺陷:无法获取命令的返回结果. 也许你可以用`echo comm ...

  4. popen()与system()

    一.popen() 用途:执行shell命令(并读取其输出或向其发送一些输入) 特点:通过管道来与shell命令进行通信 二.system()

  5. 在LoadRunner中执行命令行程序之:popen()取代system()

    我想大家应该都知道在LoadRunner可以使用函数system()来调用系统指令,结果同在批处理里执行一样. 但是system()有个缺陷:无法获取命令的返回结果. 也许你可以用`echo comm ...

  6. python,adb,分别给多个设备安装多个apk文件,os.popen(); os.system; os.path.splitext(); a.split(' \t'); readlines(); append(); os.path.join(); time.sleep();

    #encoding:utf-8import os,time#=======================查找手机设备序列号=============a='adb devices'b=os.popen ...

  7. python中os.popen, os.system()区别

    直接上个例子吧,注意结果,os.system的结果只是命令执行结果的返回值,执行成功为0: >>> a=os.system('ls') Applications Movies pyt ...

  8. Python_cmd的各种实现方法及优劣(subprocess.Popen, os.system和commands.getstatusoutput)

    http://blog.csdn.net/menglei8625/article/details/7494094

  9. [转载]Linux下关于system调用

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

随机推荐

  1. Linux 和类 Unix 系统上5个最佳开源备份工具

    转载:http://linux.cn/article-4623-weixin.html#rd?sukey=cbbc36a2500a2e6cb7678c4d38b691a9fa7403b259f898e ...

  2. Unity 游戏框架搭建 (九) 减少加班利器-QConsole

    为毛要实现这个工具? 在我小时候,每当游戏在真机运行时,我们看到的日志是这样的. 没高亮啊,还有乱七八糟的堆栈信息,好干扰日志查看,好影响心情. 还有就是必须始终连着usb线啊,我想要想躺着测试... ...

  3. mysql存储过程和函数(一)

    存储过程和函数是事先经过编译并存储在数据库的一段sql语句集合,调用存储过程和函数可以简化应用程序开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对提高数据运行效率是有好处的. 存储过程和 ...

  4. MySQL的数据类型(二)

    MySQL中提供了多种对字符数据的存储类型,不同的版本可能有所差异.以5.0版本为例,MySQL包括了CHAR.VARCHAR.BINARY.VARBINARY.BLOB.TEXT等多种字符串类型. ...

  5. FastJson反序列化漏洞利用的三个细节 - TemplatesImpl的利用链

    0. 前言 记录在FastJson反序列化RCE漏洞分析和利用时的一些细节问题. 1. TemplatesImpl的利用链 关于 parse 和 parseObject FastJson中的 pars ...

  6. jsp+spring+jquery+ajax的简单例子

    初学b/s编程,花费了许多时间,进度颇慢! 不过终于完成了一个简单的例子: jsp代码 <%@ page language="java" contentType=" ...

  7. jsonp跨域请求360数据乱码解决办法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  8. 大数据开发从入门小白到删库跑路(一)- 获取Hadoop

    Hadoop是一个可以通过相对简单编程模型实现跨多台计算机集群分布式处理大型数据集的框架.它不是依赖于高额成本的硬件可靠性来提供高可用性,Hadoop的设计能从单个服务器扩展到数千台机器,每个机器提供 ...

  9. jQuery做一个小小的移动图片的位置

    样式图点击按钮移动: jQuery代码如下: $(function () { //上            $("#btnUp").click(function () { var ...

  10. djangorestframework怎么这么好用!

    一年前就已经用过restframework, 当时觉得这个只是给web框架打辅助的, 他能实现的我也都实现(可能没有那么好用, 嘿嘿) 但是我有一种东西叫做效率, 时间就是金钱, 别人造好的就直接用就 ...