在程序中执行shell命令

时间:2023-12-25 18:45:49

在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执行命令。