linux系统编程之进程(七):system()函数使用【转】

本文转载自:http://www.cnblogs.com/mickole/p/3187974.html

一,system()理解

功能:system()函数调用“/bin/sh -c command”执行特定的命令,阻塞当前进程直到command命令执行完毕

原型:

int system(const char *command);

返回值:

如果无法启动shell运行命令,system将返回127;出现不能执行system调用的其他错误时返回-1。如果system能够顺利执行,返回那个命令的退出码。

说明:

man帮助:

       #include <stdlib.h>

       int system(const char *command);

DESCRIPTION 
       system()  executes a command specified in command by calling /bin/sh -c 
       command, and returns after the command has been completed.
  During exe- 
       cution  of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT 
       will be ignored.

RETURN VALUE 
       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 non-zero if the shell 
       is available, and zero if not.

       system() does not affect the wait status of any other children.

二,system()函数原理

system函数执行时,会调用fork、execve、waitpid等函数。

linux版system函数的源码:

复制代码
int system(const char * cmdstring){pid_t pid;int status;if(cmdstring == NULL){        return (1);}if((pid = fork())<0){status = -1;}else if(pid == 0){execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);_exit(127); //子进程正常执行则不会执行此语句}else{while(waitpid(pid, &status, 0) < 0){
                 if(errno != EINTER){status = -1;break;}}}return status;}
复制代码
  • 函数说明 
    system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。 
    在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。 
    返回值 
    =-1:出现错误  
    =0:调用成功但是没有出现子进程  
    >0:成功退出的子进程的id 
    如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值>。如果system()调用成功则最后会返回 
    执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。 
    附加说明 
    在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。

system函数对返回值的处理,涉及3个阶段:


阶段1:创建子进程等准备工作。如果失败,返回-1。 
阶段2:调用/bin/sh拉起shell脚本,如果拉起失败或者shell未正常执行结束(参见备注1),原因值被写入到status的低8~15比特位中。system的man中只说明了会写了127这个值,但实测发现还会写126等值。 
阶段3:如果shell脚本正常执行结束,将shell返回值填到status的低8~15比特位中。 
备注1: 
只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。 
比如:不管shell脚本中返回什么原因值,是0还是非0,都算正常执行结束。即使shell脚本不存在或没有执行权限,也都算正常执行结束。 
如果shell脚本执行过程中被强制kill掉等情况则算异常结束。

如何判断阶段2中,shell脚本子进程是否正常执行结束呢?系统提供了宏:WIFEXITED(status)。如果WIFEXITED(status)为真,则说明正常结束。 
如何取得阶段3中的shell返回值?你可以直接通过右移8bit来实现,但安全的做法是使用系统提供的宏:WEXITSTATUS(status)。

由于我们一般在shell脚本中会通过返回值判断本脚本是否正常执行,如果成功返回0,失败返回正数。 
所以综上,判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立: 
(1)-1 != status 
(2)WIFEXITED(status)为真 
(3)0 == WEXITSTATUS(status) 
注意: 
根据以上分析,当shell脚本不存在、没有执行权限等场景下时,以上前2个条件仍会成立,此时WEXITSTATUS(status)为127,126等数值。 
所以,我们在shell脚本中不能将127,126等数值定义为返回值,否则无法区分中是shell的返回值,还是调用shell脚本异常的原因值。shell脚本中的返回值最好多1开始递增。

示例程序:

复制代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>#define EXIT_ERR(m) \
do\
{\perror(m);\exit(EXIT_FAILURE);\
}\
while (0);\int main(void)
{int status ;status = system("ls -l|wc -l");if(status == -1){EXIT_ERR("system error");}else{if(WIFEXITED(status)){if(WEXITSTATUS(status) == 0)printf("run command successful\n");elseprintf("run command fail and exit code is %d\n",WEXITSTATUS(status));}elseprintf("exit status = %d\n",WEXITSTATUS(status));}return 0;
}
复制代码

结果:

QQ截图20130713131149

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装了最新版本的java 用友nc打不开_NC无法安装客户端插件,不能进入用友NC系统登陆界面...

NC无法安装客户端插件&#xff0c;不能进入用友NC系统登陆界面问题现象现象1&#xff1a;可以打开web界面&#xff0c;但无法进入登陆界面&#xff0c;一直停留在右图所示界面。现象2&#xff1a;系统提示安全警告问题原因在使用IE首次登录NC系统时&#xff0c;系统会自动下载N…

汉王云名片识别(SM)组件开发详解

大家好&#xff0c;最近在DeviceOne平台上做了一个汉王云名片识别的功能组件。下面把我开发过程给大家做一个分享&#xff0c;希望可以帮助到大家。 下面我把我的思路给大家讲解一下。1.找到我要集成的sdk&#xff0c;也就是汉王云名片的sdk下载&#xff08;android和ios&#…

[App Store Connect帮助]八、维护您的 App(4.2)查看评分与评论

您可以查看 App 的总评分或单个顾客评论。如有必要&#xff0c;您可以针对某条评论报告问题。 【注】顾客可以为您的 iOS 和 macOS App 评分并撰写评论&#xff0c;但只能为 Apple TVOS App 评分。 必要职能&#xff1a;“帐户持有人”职能、“管理”职能、“App 管理”职能、“…

visio studio json工具_《产品经理入门指南》彩蛋2:别技淫原型图!你的Visio和Balsamiq Mockup入门了吗?...

温馨提示&#xff1a;如果你有关于产品经理方面的任何问题&#xff0c;欢迎关注我的微信公众号与我互动。最新的免费系统的产品经理课程《老司机带你做产品》已经推出&#xff0c;请关注微信公众号&#xff1a;iamliuwenzhi很多产品新人刚开始工作时&#xff0c;喜欢一拿到需求…

渐进式web应用程序_通过渐进式Web应用程序吸引用户并增强他们的体验

渐进式web应用程序by Dave Gray戴夫格雷(Dave Gray) 通过渐进式Web应用程序吸引用户并增强他们的体验 (Engage your users and enhance their experience with Progressive Web Apps) 什么是渐进式Web应用程序&#xff1f; (What is a Progressive Web App?) A Progressive W…

mysql牵引例子_MySQL学习06(事务和索引)

事务概述什么是事务事务就是将一组SQL语句放在同一批次内去执行如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行MySQL事务处理只支持InnoDB和BDB数据表类型事务的ACID原则原子性(Atomic)整个事务中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成&#…

android操作系统 真的吗_旋挖机培训学校真的能学会吗,旋挖钻机到底有哪些操作系统...

旋挖机培训学校真的能学会吗添加微&#xff1a;yywyyc 旋挖钻机到底有哪些操作系统【前言】很多使用旋挖钻机或者想要了解旋挖钻机的工程公司可能不是特别了解旋挖钻机本身的系统以及部件&#xff0c;本篇文章针对旋挖钻机的操作系统来给大家介绍一下&#xff0c;让大家了…

WebAPI 2参数绑定方法

简单类型参数 Example 1: Sending a simple parameter in the Url [RoutePrefix("api/values")] public class ValuesController : ApiController {// http://localhost:49407/api/values/example1?id2[Route("example1")][HttpGet]public string Get(int…

推荐几个自己经常去的一些博客和网站

唐巧的技术博客objc中国Ray WenderlichCocoaDocs.orgNSHipsterLukes HomepageCocoabit | 做自己喜欢的事情转载于:https://www.cnblogs.com/faceup/p/10423259.html

创建hugo博客_Hugo + Firebase:如何在几分钟内免费创建自己的静态网站

创建hugo博客by Aravind Putrevu通过Aravind Putrevu Hugo Firebase&#xff1a;如何在几分钟内免费创建自己的静态网站 (Hugo Firebase: How to create your own static website for free in minutes) Ever thought of having your own website for putting up your projec…

探测与响应是各企业机构在2017年的首要安全事务

作者系&#xff1a;Gartner首席研究分析师 Sid Deshpande &Gartner研究总监 Lawrence Pingree 2017年&#xff0c;各个企业正在改变其安全支出战略&#xff0c;从仅注重防御转而更加关心探测和响应程度。2017年的全球信息安全支出预计将达到900亿美元&#xff0c;相较2016年…

java怎么引入html文件路径_如何在public_html中读取文件但在域外?使用相对路径...

我正在尝试从我的(附加组件)域目录之外的目录中读取文件 . 这是我的目录结构&#xff1a;public_html /domain /file_read.phpfile_write.phpsensitive /file.dat虽然我能够使用“../sensitive/file.dat”写入敏感&#xff0c;但我无法使用相同的方法进行读取 . 有什么想法吗&a…

JS基本概念(3)

【5】操作符 &#xff08;1&#xff09;一元操作符&#xff1a;只能操作一个值的操作符 递增、递减操作符a --a 前置    a a-- 后置&#xff08;这四个操作符对任何值都适用&#xff0c;不能转换成数字的转换为NaN&#xff09; 一元加、一元减操作符&#xff0…

csv文件怎么转成excel_Java读写excel,excel转成json写入磁盘文件

pom读写excel主要的dependency<dependency> <groupId>org.apache.poigroupId> <artifactId>poiartifactId> <version>3.16version> dependency> <dependency> <groupId>org.apache.poigroupId> …

如何用Ant Design Pro框架做项目省力

1、熟悉React所有语法&#xff0c;以及redux、redux-saga、dva、一类的库的能力 2、灵活运用该框架提供的基础UI组件&#xff0c;想方设法利用现有的UI组件进行组合&#xff0c;尽可能减少工作量 转载于:https://www.cnblogs.com/ww01/p/10430553.html

通过在Chipotle用餐了解模板方法设计模式

by Sihui Huang黄思慧 通过在Chipotle用餐了解模板方法设计模式 (Understanding the Template Method design pattern by eating at Chipotle) Object-Oriented Design Patterns in Life— gain an intuitive understanding of OO design patterns by linking them with real-…

Coriant助力Aureon部署100Gbps光纤网络

根据相关消息显示&#xff0c;光传输设备厂商Coriant日前表示已经向网络传输和业务通信服务供应商Aureon Technology提供了7100纳米分组光传输平台&#xff0c;帮助其进行100Gbps光纤网络的拓展。 该服务供应商&#xff08;Aureon&#xff09;将利用该分组光传输系统&#xff0…

python class tynu()_Visual Studio Express | Teraz Visual Studio Community

Program Visual Studio 2019 jest teraz dostępnyDostosowany instalatorTwrz aplikacje w technologiach WPF, WinForms, platformy uniwersalną systemu Windows, Win32, Android, iOS i innych — wszystko to za pomocą jednego środowiska IDE zapewniającego wszyst…

css样式中如何设置中文字体?

代码如下: .selector{font-family: SimHei,"微软雅黑",sans-serif;} 注意&#xff1a;加上中文名“微软雅黑”是为了兼容opera浏览器&#xff0c;中文字体名必须加上引号&#xff08;单引号双引号都可以&#xff09;。 MicrosoftJhengHei为微软正黑体&#xff0c;STH…

前端做CRM管理系统是做什么_代办行业的CRM客户关系管理系统应该是什么样子的?...

随着互联网的深耕细化&#xff0c;很多企业也在不断优化自己的办公方式&#xff0c;以优化企业的办公流程&#xff0c;提高企业的办事效率。因此实现办公自动化&#xff0c;或者说实现数字化办公就需要逐渐提上日程。今天给大家讲讲可以帮助代办行业实现办公自动化的产品&#…