制作一个简易的shell
- 一、设置命令行
- 二、获取输入的命令
- 第一步和第二步代码细节剖析
- 三、命令行字符串分割
- 第三步细节剖析
- 四、执行命令
- 五、代码汇总及演示
想要制作一个简易的shell,过程分为四步
一、设置命令行
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<errno.h>
#define SIZE 512
#define SEP " "
#define ZERO '\0'
#define NUM 32const char *get_username(){const char *name=getenv("USER");if(name==NULL) return "None";return name;}const char *get_hostname(){const char *hostname=getenv("HOSTNAME");if(hostname==NULL) return "None";return hostname;}const char *get_cwd(){const char* cwd=getenv("PWD");if(cwd==NULL) return "None";return cwd;} void make_commandline_and_print(){char line[SIZE];const char *username=get_username();const char *hostname=get_hostname();const char *cwd=get_cwd();snprintf(line,sizeof(line),"[%s@%s %s]> ",username,hostname,cwd);printf("%s",line);fflush(stdout);}int main()
{// 设置命令行make_commandline_and_print();return 0;
}
二、获取输入的命令
int get_user_command(char command[],size_t n){char *s=fgets(command,n,stdin);if(s==NULL) return -1;command[strlen(command)-1]=ZERO;return strlen(command);}
int main()
{char usercommand[SIZE];int n=get_user_command(usercommand,sizeof(usercommand));return 0; }
第一步和第二步代码细节剖析
三、命令行字符串分割
void split_command(char command[],size_t n)
{// 先处理第一个Argv[0]=strtok(command,SEP);int index=1;while((Argv[index++]=strtok(NULL,SEP)));// 特意设置=,先赋值,再判断,分割之后strtok会返回NULL,// 刚好Argv的最后一个元素是NULL,判断结束
}int main()
{split_command(usercommand,sizeof(usercommand));return 0; }
第三步细节剖析
四、执行命令
void Die()
{exit(1);
}void executecommand()
{pid_t id=fork();if(id<0) Die();else if(id==0){// childexecvp(Argv[0],Argv);exit(errno);}else{// father int status=0;pid_t rid=waitpid(id,&status,0);if(rid>0){// TODO}}
}int main()
{executecommand();return 0; }
五、代码汇总及演示