本文主要是介绍【Linux】自定义shell(命令行解释器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原理: shell是命令行解释器,当有命令需要执行时,shell创建子进程,让子进程执行命令,而shell只需等待子进程退出即可。
其中我们使用了下面这几个函数:
- 获取命令行(fgets函数)。
- 解析命令行(strtok分割字符串)。
- 创建子进程(fork函数)。
- 替换子进程(exec函数族)。
- 等待子进程退出(waitpid函数)
实现简易命令解释行的过程中我们遇到了一些问题:
cd,export等內键命令,在子进程下修改无法影响到bash,所以我们增加了函数来判断命令是否为內键命令,并判断其是否为空,使用chdir修改其所在路径通过argv[1]取出要到的路径。
但是我们发现如果进入的是.. 上级路径的话 就会变成下面这样
我们的目录名称直接变成了..,此时我们需要使用 snprintf函数 将temp写入pwd中。
以下为简易实现的代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#define SIZE 1024
#define MAX_ARGC 64
#define SEP " "
char *argv[MAX_ARGC];
char PWD[SIZE];const char* HostName(){char *hostname=getenv("HOSTNAME");if(hostname) return hostname;else return "none";}const char* UserName() { char *hostname=getenv("USER"); if(hostname) return hostname; else return "none"; } const char* CurrentWorkDir() { char *hostname=getenv("PWD"); if(hostname) return hostname; else return "none"; } char *Home(){return getenv("HOME");}int Interactive(char out[],int size){printf("[%s@%s %s]$",UserName(),HostName(),CurrentWorkDir());fgets(out,size,stdin);out[strlen(out)-1]=0;//'\0'return strlen(out);}
void Split(char in[]){int i=0;argv[i++]=strtok(in,SEP);while(argv[i++]=strtok(NULL,SEP));}void Execute(){pid_t id=fork();if(id==0){execvp(argv[0],argv);exit(1);}pid_t rid=waitpid(id,NULL,0);printf("run done,rid: %d\n",rid);}int BuildinCmd(){int ret=0;//1.检测是否为内建命令 是1 否0if(strcmp("cd",argv[0])==0) {ret=1;char *target=argv[1];if(!target) target=Home();chdir(target);char temp[1024];getcwd(temp,1024);snprintf(PWD,SIZE,"PWD=%s",temp);putenv(PWD);}//2.执行return ret;}int main(){//1.打印命令行提示符,获取用户输入的命令字符串while(1){char commandline[SIZE];int n= Interactive(commandline,SIZE);if(n==0) continue;//2.对命令行进行切割Split(commandline);//3.处理内建命令n=BuildinCmd();if(n) continue;//4.执行这个命令Execute();}//int j=0;//for(j=0;argv[j];j++)//{// printf("argv[%d]: %s\n",j,argv[j]);//}return 0;}
Makefile文件的配置:
myshell:myshell.cgcc -o $@ $^
.PHONY:cleanrm -f myshell
演示结果如下
这篇关于【Linux】自定义shell(命令行解释器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!