C语言中system()函数的用法总结(转)
system()函数功能强大,很多人用却对它的原理知之甚少先看linux版system函数的源码:
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h> int system(const char * cmdstring)
{
pid_t pid;
int status; if(cmdstring == NULL){
return ();
} if((pid = fork())<){
status = -;
} else if(pid = ){
execl("/bin/sh", "sh", "-c", cmdstring, (char *));
exit(); //子进程正常执行则不会执行此语句
} else{
while(waitpid(pid, &status, ) < ){
if(errno != EINTER){
status = -;
break;
}
}
} return status;
}
分析一下原理估计就能看懂了:
当system接受的命令为NULL时直接返回,否则fork出一个子进程,因为fork在两个进程:父进程和子进程中都返回,这里要检查返回的pid,fork在子进程中返回0,在父进程中返回子进程的pid,父进程使用waitpid等待子进程结束,子进程则是调用execl来启动一个程序代替自己,execl("/bin/sh", "sh", "-c", cmdstring, (char*)0)是调用shell,这个shell的路径是/bin/sh,后面的字符串都是参数,然后子进程就变成了一个shell进程,这个shell的参数是cmdstring,就是system接受的参数。在windows中的shell是command,想必大家很熟悉shell接受命令之后做的事了。
再解释下fork的原理:当一个进程A调用fork时,系统内核创建一个新的进程B,并将A的内存映像复制到B的进程空间中,因为A和B是一样的,那么他们怎么知道自己是父进程还是子进程呢,看fork的返回值就知道,上面也说了fork在子进程中返回0,在父进程中返回子进程的pid。
windows中的情况也类似,就是execl换了个又臭又长的名字,参数名也换的看了让人发晕的,我在MSDN中找到了原型,给大家看看:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
用法见下:
ShellExecute(NULL, "open", "c:\\a.reg", NULL, NULL, SW_SHOWNORMAL);
你也许会奇怪 ShellExecute中有个用来传递父进程环境变量的参数 lpDirectory,linux中的execl却没有,这是因为execl是编译器的函数(在一定程度上隐藏具体系统实现),在linux中它会接着产生一个linux系统的调用 execve, 原型见下:
int execve(const char * file,const char **argv,const char **envp);
看到这里就会明白为什么system()会接受父进程的环境变量,但是用system改变环境变量后,system一返回主函数还是没变。原因从system的实现可以看到,它是通过产生新进程实现的,从我的分析中可以看到父进程和子进程间没有进程通信,子进程自然改变不了父进程的环境变量。
使用了system函数就能执行dos指令。
#include <stdio.h>
#include <stdlib.h> xiaoyu()
{
char *a;
int n=;
FILE *f;
f=fopen("file.bat","w+");/*新建一个批处理*/
if(f==NULL) {
exit();
} a="echo"; /*DOS命令*/
for(n=;n<=;n++) {/*大写A-Z*/
fprintf(f,"%s %c\n",a,n);/*利用ASCII码输出A-Z,写出批处理*/
}
fclose(f);
system("file.bat");/*运行批处理*/
} int main(int argc, char argv[])
{
char *string; xiaoyu();
string="echo C语言的system函数\n";/*输出中文*/
system(string);
system("pause");/*程序暂停*/
return ;
}
C中可以使用DOS命令,以后编程通过调用DOS命令很多操作就简单多了。
C语言中system()函数的用法总结(转)的更多相关文章
- C语言中sprintf()函数的用法
sprintf函数的用法 1.该函数包含在stdio.h的头文件中. 2.sprintf和平时我们常用的printf函数的功能很相似.sprintf函数打印到字符串中,而printf函数打印输出到屏幕 ...
- C语言中strtod()函数的用法详解
函数原型: #include <stdlib.h> double strtod(const char *nptr, char **endptr); C语言及C++中的重要函数. 名称含义 ...
- C语言中qsort函数用法
C语言中qsort函数用法-示例分析 本文实例汇总介绍了C语言中qsort函数用法,包括针对各种数据类型参数的排序,非常具有实用价值非常具有实用价值. 分享给大家供大家参考.C语言中的qsort ...
- R语言中apply函数
前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是为什么呢?原因在于R的循环操作for和while,都是基于R语言 ...
- 使用C语言中qsort()函数对浮点型数组无法成功排序的问题
一 写在开头 1.1 本节内容 本节主要内容是有关C语言中qsort()函数的探讨. 二 问题和相应解决方法 qsort()是C标准库中的一个通用的排序函数.它既能对整型数据进行排序也能对浮点型数据进 ...
- C语言中malloc函数返回值是否需要类型强制转换问题
1. 在C语言中, 如果调用的函数没有函数原型, 则其返回值将默认为 int 型. 考虑调用malloc函数时忘记了 #include <stdlib.h>的情况 此时malloc函数返回 ...
- (转)C语言中Exit函数的使用
C语言中Exit函数的使用 exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如 ...
- C语言中malloc函数的理解
在C语言中malloc函数主要是用在堆内存的申请上,使用malloc函数时,函数会返回一个void *类型的值,这个值就是你申请的堆内存的首地址:为什么返回的地址是一个void *类型的地址呢?首先我 ...
- 关于C语言中printf函数“输出歧视”的问题
目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...
随机推荐
- Wordpress 标题设置
使用标题格式:首页(网站标题 - 网站副标题),其他页面(页面标题 | 网站标题) 在后台找到头部文件head.php <?php wp_title('|', true, 'right'); e ...
- 安装php扩展库
无法加载'pdo_mysql' ,因为需要pdo这个module.PHP Warning: Cannot load module 'pdo_mysql' because required module ...
- C语言 ---- 数组 iOS学习-----细碎知识点总结
#pragma mark - 数组:用来存放同一数据类型的数据 // 数组的定义:类型说明符 数组名[常量表达式] = {值1, 值2, 值3...}; // 定义一个float类型的数组,用来 ...
- 使用Mod_JK链接Apache和Tomcat
There are many potential problems associated with the default configuration of mod_jk. Let's say it ...
- 简单理解javascript的原型prototype
原型和闭包是Js语言的难点,此文主要讲原型. 每一个方法都有一个属性是 prototype 每一个对象都有一个属性是 _proto_ 一旦定义了原型属性或原型方法,则所有通过该构造函数实例化出来的所有 ...
- Windows7中IIS简单安装与配置(详细图解)
最近工作需要IIS,自己的电脑又是Windows7系统,找了下安装的方法,已经安装成功.在博客里记录一下,给需要的朋友,也是给自己留个备份,毕竟我脑子不是很好使. 一.首先是安装IIS.打开控制面板, ...
- Nhiberate (二) 搭项目
使用: visual studio 2015 ;SQL SERVER 2012. 参考.测试可用 其中有点不太一样的地儿, ISession 的泛型方法: 用了 QueryOver<>,转 ...
- 安装docker-compose
下载到合适的位置 curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s` ...
- Struts(八):动态方法调用
动态方法调用:通过url动态调用action中的方法. 默认情况下,Struts的动态方法调用处于禁用状态. 测试定义一个action类: package com.dx.actions; public ...
- Struts2(四):在Action中如何访问Web资源
1.什么WEB资源? HttpServletRequest,HttpServletRespone,HttpApplication,ServletContext,HttpSession等原生Servle ...