UNIX外壳实现

目的:设计一个外壳接口,可以用来接受用户的命令,在一个单独的进程中执行用户命令。

外壳接口:为用户提供提示符,便于下一个命令的输入。

实现过程:父进程读取用户命令行的输入,然后创建一个单独的子进程来完成这个命令。

外壳基本轮廓:以main()函数提供osh>命令符为例:

#include <stdio.h>
#include <unistd.h>
int main(){
	char *args[MAX_LINE/2 + 1];
	int should_run = 1;

	while(should_run){
		printf("osh>"); 
		fflush(stdout);   
	}
	return 0;
}

fork()与exec的使用和区别:

系统调用fork():创建子进程,父进程和子进程之间共享代码段(建立相同的程序副本),仅通过复制指令、用户数据和系统数据段来创建从现存进程克隆的新进程,该新进程不是从程序初始化得来的,所以旧进程和新进程执行同样的指令。

系统调用exec():是以新的进程去代替原来的进程,但进程的PID保持不变。也就是exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。

一般使用方法为:先调用fork(),再使用exec()来达到提高效率的目的。

exit():终止进程,如写如exit(1)来结束进程。

系统调用wait():等待子进程的终止。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#define MAX_LINE &

int main(){
	char *args[MAX_LINE/2 + 1];
	int should_run = 1;

	while(should_run){
		printf("osh>");  //设置提示符为‘osh>‘
		fflush(stdout);   
		
		char c;
		int i = 0;      
		do{			
			char *s = (char*)malloc( 128);
			scanf("%s",s);
			c = getchar();
			args[i++] = s;
			if(strcmp(args[0],"exit") == 0){should_run = 0;}//用户在提示符后面输入exit后,should_run为0并且终止;
			if(strcmp(args[i-1],"&") == 0){i--;} //输入& 显示waitpid:success

		}while(c == ' ');
		
		args[i] = NULL;
		pid_t id=fork();	//创建子进程,父进程和子进程之间共享代码段(建立相同的程序副本)
		if (id < 0){
			perror("fork");	//抛出异常
		}
		if(id == 0)  {
			execvp(args[0],args);   //exec系列的一种,用于运行新程序
			exit(1);				//调用exit()来终止程序
		}
		else{
	    	int status = 0;
			pid_t ret = waitpid(id,&status,0);//等待子进程结束
			if(ret > 0 && WIFEXITED(status))
			{}
			else{perror("waitpid");}
		}
	}
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小半、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值