shell
shell就是操作系统提供给用户与操作系统进行交互的命令行界面。它可以理解为一个用户与操作系统之间的接口,用户可以通过输入命令来执行各种操作,如文件管理、进程控制、软件安装等。Shell还可以通过脚本编程实现自动化任务。
常见的Unix系统中使用的默认shell是Bash。除了Bash,还有其他一些常见的shell,如 C Shell、Kron Shell 等,它们对于不同的用户需求和习惯提供了不同的特性和语法。
自定义Shell
打印
获取的字符串分割
执行命令
一些问题
内建命令的处理
原码
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>#defineSIZE1024#defineMAX_ARGC64#defineSEP" "char*argv[MAX_ARGC];char pwd[SIZE];char env[SIZE];// for testint lastcode =0;constchar*HostName(){char*hostname =getenv("HOSTNAME");if(hostname)return hostname;elsereturn"None";}constchar*UserName(){char*hostname =getenv("USER");if(hostname)return hostname;elsereturn"None";}constchar*CurrentWorkDir(){char*hostname =getenv("PWD");if(hostname)return hostname;elsereturn"None";}char*Home(){returngetenv("HOME");}intInteractive(char out[],int size){// 输出提示符并获取用户输入的命令字符串"ls -a -l"printf("[%s@%s %s]$ ",UserName(),HostName(),CurrentWorkDir());fgets(out, size,stdin);
out[strlen(out)-1]=0;//'\0'returnstrlen(out);}voidSplit(char in[]){int i =0;
argv[i++]=strtok(in, SEP);// "ls -a -l"while(argv[i++]=strtok(NULL, SEP));if(strcmp(argv[0],"ls")==0){
argv[i-1]=(char*)"--color";
argv[i]=NULL;}}voidExecute(){pid_t id =fork();if(id ==0){// 让子进程执行命名execvp(argv[0], argv);exit(1);}int status =0;pid_t rid =waitpid(id,&status,0);if(rid == id) lastcode =WEXITSTATUS(status);//printf("run done, rid: %d\n", rid);}intBuildinCmd(){int ret =0;// 1. 检测是否是内建命令, 是 1, 否 0if(strcmp("cd", argv[0])==0){// 2. 执行
ret =1;char*target = argv[1];//cd XXX or cdif(!target) target =Home();chdir(target);char temp[1024];getcwd(temp,1024);snprintf(pwd, SIZE,"PWD=%s", temp);putenv(pwd);}elseif(strcmp("export", argv[0])==0){
ret =1;if(argv[1]){strcpy(env, argv[1]);putenv(env);}}elseif(strcmp("echo", argv[0])==0){
ret =1;if(argv[1]==NULL){printf("\n");}else{if(argv[1][0]=='$'){if(argv[1][1]=='?'){printf("%d\n", lastcode);
lastcode =0;}else{char*e =getenv(argv[1]+1);if(e)printf("%s\n", e);}}else{printf("%s\n", argv[1]);}}}return ret;}intmain(){while(1){char commandline[SIZE];// 1. 打印命令行提示符,获取用户输入的命令字符串int n =Interactive(commandline, SIZE);if(n ==0)continue;// 2. 对命令行字符串进行切割Split(commandline);// 3. 处理内建命令
n =BuildinCmd();if(n)continue;// 4. 执行这个命令Execute();}return0;}
版权归原作者 诡异森林。 所有, 如有侵权,请联系我们删除。