在linux系统下的操作中我们会经常用到shell命令来进行,一开始学习进程的时候对于shell命令也进行了思考,认为shell命令就是一个进程的外壳,经过了后来的学习对于这一点也有了更多的认识。

用过shell命令的都是知道,shell命令有很多,比如去一个目录中文件名的列表是用ls,新建一个文件夹用mkdir等。其实,我们用的shell命令“ls”、“-c”就是shell这个程序的参数,下面我们通过编程来实现shell中的ls命令并将结果写到temp.txt文件中。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/wait.h>

#define MAX 1024

int system(const char * cmdstring);

int main(void)

{

       int fd , n;

       char buf[MAX];          //保存文件内容的缓冲区

       if(system("ls > temp.txt") == -){ //使用system执行ls命令,并将结果输出到temp.txt文件中

              perror("fail to exec command");

              exit();

       }

       if((fd = open("temp.txt",O_RDWR)) == -){//打开temp.txt文件

              perror("fail to open");

              exit();

       }

       printf("%d\n",fd);

       if((n = read(fd, buf ,MAX)) == -){   //读文件内容

              perror("fail to read");

              exit();

       }

       buf[n] = '\0';   //添加'\0'结束符

       printf("%s",buf);  //文件内容自带'\n'

       return ;

}

这一部分是通过调用system函数实现shell中的ls命令,这一部分是简单的函数调用、文件读写和显示。这里的system函数就相当于是shell,system函数的执行流程分为两部分,首先调用system函数的进程创建一个子进程,并且调用wait函数等待子进程执行完毕。其次是在子进程中调用excel函数加在shell运行cmdstring中的指令,程序如下。

//system1函数的原理性实现

int system(const char * cmdstring)

{

       pid_t pid;

       int status;

       if(cmdstring == NULL)  //如果命令字符串为空,则返回1

              return ;

       pid = fork();          //创建一个子进程

       if(pid < ){

              status = -;

       }else if(pid == ){                 //子进程

              execl("/bin/sh","sh","-c",cmdstring,NULL);  //加载shell,由shell执行命令

              _exit();                                                               //如果执行程序失败,子程序退出,返回127

       }

       if(waitpid(pid, &status, ) == -)             //wait函数出错,抛弃得到的无用状态  

              status = -;

       return status;                                   //返回退出状态

}

上边的程序可以看出这一段原理性实现的主要部分就是子进程这一部分代码的程序,在子进程中加载shell执行命令。

在程序中执行shell命令的更多相关文章

  1. 在 Ruby 中执行 Shell 命令的 6 种方法

    我们时常会与操作系统交互或在 Ruby 中执行 Shell 命令.Ruby为我们提供了完成该任务的诸多方法. Exec Kernel#exec 通过执行给定的命令来替换当前进程,例如: $ irb & ...

  2. python中执行shell命令的几个方法小结(转载)

    转载:http://www.jb51.net/article/55327.htm python中执行shell命令的几个方法小结 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014- ...

  3. vim中执行shell命令小结

    vim中执行shell命令,有以下几种形式 1):!command 不退出vim,并执行shell命令command,将命令输出显示在vim的命令区域,不会改变当前编辑的文件的内容 例如:!ls -l ...

  4. python中执行shell命令的几个方法小结

    原文 http://www.jb51.net/article/55327.htm 最近有个需求就是页面上执行shell命令,第一想到的就是os.system, os.system('cat /proc ...

  5. python中执行shell命令行read结果

    +++++++++++++++++++++++++++++ python执行shell命令1 os.system 可以返回运行shell命令状态,同时会在终端输出运行结果 例如 ipython中运行如 ...

  6. vim中执行shell命令

    1):!command   不退出vim,并执行shell命令command,将命令输出显示在vim的命令区域,不会改变当前编辑的文件的内容   例如   :!ls -l   特别的可以运行:!bas ...

  7. 【译】 AWK教程指南 6在AWK程序中使用Shell命令

    awk程序中允许调用Shell指令,并提供管道解决awk与系统间数据传递的问题.所以awk很容易使用系统资源,读者可利用这个特点来编写某些适用的系统工具. 范例:写一个awk程序来打印出线上人数. 将 ...

  8. 「Python」6种python中执行shell命令方法

    用Python调用Shell命令有如下几种方式: 第一种: os.system("The command you want"). 这个调用相当直接,且是同步进行的,程序需要阻塞并等 ...

  9. 在c++程序中执行DOS命令

    转自博客:http://blog.csdn.net/ypist/article/details/8485049 #1,system()方式 在C盘根目录下新建文件夹,名称为12: system(&qu ...

随机推荐

  1. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  2. [LeetCode] Valid Parentheses 验证括号

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...

  3. BZOJ 3237: [Ahoi2013]连通图

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1161  Solved: 399[Submit][Status ...

  4. StringIO和BytesIO

    1. StringIO 很多时候,数据读写不一定是文件,也可以在内存中读写. StringIO顾名思义就是在内存中读写str. 要把str写入StringIO,我们需要先创建一个StringIO,然后 ...

  5. list,tuple,dict,set常用方法

    Python中list,tuple,dict,set常用方法 collections模块提供的其它有用扩展类型 from collections import Counter from collect ...

  6. express不是内部或外部命令

    网上找了一下原因,是因为express在4.0以后把命令工具单独分出来了,所以安装完express后,还得再安装express-generator: 如果不是采用的全局安装,则需要把 "安装 ...

  7. redis-内存异常 Redis is configured to save RDB snapshots解决

    连接reids获取数据时提示 Redis is configured to save RDB snapshots, but is currently not able to persist on di ...

  8. Android疑难杂症收集

    在渲染前获取 View 的宽高 5种手势工具类 软键盘用法总结 Android中Shape的使用 Android只能动态注册的广播Action Android 悬浮窗权限各机型各系统适配大全 录音权限 ...

  9. C# mysql 获取所有表名

    public static List<string> GetAllTableName()        {            List<string> retNameLis ...

  10. BZOJ 1876: [SDOI2009]SuperGCD

    1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3060  Solved: 1036[Submit][St ...