思路:先创建一个父进程,然后在父进程中创建一个子进程,而在子进程中调用exec函数族,父进程所要做的只是等待子进程的结束,然后再次循环等待用户输入下一条命令。注:因为要模拟的是bash,所以在一条命令执行完成了后,执行命令的进程结束了,但是bash并没有结束(即不能在父进程中调用exec函数族,否则父进程也会结束,不符合实际),而是等待刚才输入的命令结束后,再次提示用户输入下一条命令,直到用户输入了exit为止。
代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define N 64
int main(int argc, char *argv[])
{
char buf[N] = {0}; //定义并初始化一个字符串数组
char *arg[N]; //定义一个指针数组
pid_t pid;
int i = 0, j;
while (1)
{
printf("linux@ubuntu:~$");
fgets(buf, N, stdin);//ls -l -a //等待用户从键盘输入,回车后将输入的内容写到buf,包括 \n,
//此时,buf数组中以\0结尾,\0 前面是 \n,显然 \n 不是命令
buf[strlen(buf)-1] = '\0'; //将buf数组中的\0前面的那个\n用\0进行覆盖
if (strcmp(buf, "exit") == 0) //看输入的是否为exit,注:没有对空格进行处理
break;
if ((pid = fork()) == -1) //创建子进程
{
perror("fork");
exit(-1);
}
if (pid == 0)
{
/* 下面是利用strtok函数将buf数值进行解析,把命令和参数分别解析出来,strtok函数的使用参见 C语言函数大全:下面是部分内容 头文件:#include <string.h> 定义函数:char * strtok(char *s, const char *delim); 函数说明:strtok()用来将字符串分割成一个个片段. 参数s 指向欲分割的字符串, 参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符. 在第一次调用时,strtok()必需给予参数s 字符串, 往后的调用则将参数s 设置成NULL. 每次调用成功则返回下一个分割后的字符串指针. 返回值:返回下一个分割后的字符串指针, 如果已无从分割则返回NULL. 范例 #include <string.h> #include <stdio.h> int main(void) { char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z"; char *delim = "-: "; char *p; printf("%s ", strtok(s, delim)); while((p = strtok(NULL, delim))) printf("%s ", p); printf("\n"); return 0; } 执行结果: ab cd ef;gh i jkl;mnop;qrs tu vwx y;z //-与:字符已经被\0 字符取代 */
arg[i] = strtok(buf, " ");
do
{
++i;
arg[i] = strtok(NULL, " ");
}while(arg[i] != NULL);
for (j = 0; j < i; j++)
printf("%s\n", arg[j]);
// char * arg[] = {"ls", "-l", "-a", NULL};
if (-1 == execvp(arg[0], arg)) //在子进程中调用execvp函数,子进程的三段被替换
{
perror("execvp");
exit(-1);
}
}
else
wait(NULL); //父进程等待子进程就是,即等待argv[0]中指向的命令执行完
}
return 0;
}