1.打印命令行 ,接受命令行输入
命令行就是,“[用户名@主机名 当前目录]$"获取这些信息都存储在Linux内核中的环境变量中,用getenv()函数取出
#include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/wait.h>
7
8 #define SIZE 1024
9
10 const char * GetUserName()
11 {
12 char * userName = getenv("USER");
13 if(userName) return userName;
14 else return "None";
15 }
16
17 const char* GetHostName()
18 {
19 char *hostname = getenv("HOSTNAME");
20 if(hostname) return hostname;
21 else return "None";
22
23 }
24
25
26 const char *GetPWDName()
27 {
28 char *hostname = getenv("PWD");
29 if(hostname) return hostname;
30 else return "None";
31
32 }
33
34 int Interactive(char out[],int size)
35 {
36 printf("[%s@%s %s]$",GetUserName(),GetHostName(),GetPWDName());
37
38 fgets(out,size,stdin);
39 out[strlen(out)-1] = '\0';
return strlen(out);
41 }
这里是主函数调用它 ,利用他的返回值(输入的字符串长度)如果为零,不进行下一项,重新打印命令行。
2.切割命令行参数
char* strtok(char* str,const char* delim);
- 首次调用:它接受两个参数(待分解的字符串、分割符字符串),函数会在str中查找delim中的任意一个字符,一旦找到,就将该字符替换为字符串结束符’\0’,并返回指向当前令牌(分隔符之前的字符串)的指针。
- 后续调用:在首次调用后,每次调用strtok,应将第一个参数设置为NULL,以便函数从上次分解的位置查找并分解字符串。
这什么是新添加的几个宏和全局变量。
int Split(char in[])
{
int i=0;
argv[i]=strtok(in,Sep);
i++;
while(argv[i++] = strtok (NULL,Sep));//故意把“==”写成“=”
}
利用stroke函数把字符串分割成一个个以Sep为分割的小字符串 。
验证一下是不是我们想要的结果。
3. 执行命令
void Execute()
62 {
63 pid_t id =fork();
64 if(id == 0)
65 {
66 execvp(argv[0],argv);
67 }
68
69 int statue = 0;
70 pid_t rid = waitpid(id,&statue,0);
71 if(rid == id)
72 {
73 lastcode=WEXITSTATUS(statue);
74 }
75 }
将处理好的命令,交给子进程进行进程程序替换。
4.处理一下内建命令
类似于这种命令,就是子进程去执行,并不能影响到父进程,无法很好的实现命令,所以这种类型的命令需要我们特殊处理一下。
int BuildinCmd()
{
int ret = 0;
// 1. 检测是否是内建命令, 是 1, 否 0
if(strcmp("cd", argv[0]) == 0)
{
// 2. 执行
ret = 1;
char *target = argv[1]; //cd XXX or cd
if(!target) target = Home();
chdir(target);
char temp[1024];
getcwd(temp, 1024);
snprintf(pwd, SIZE, "PWD=%s", temp);
putenv(pwd);
}
else if(strcmp("export", argv[0]) == 0)
{
ret = 1;
if(argv[1])
{
strcpy(env, argv[1]);
putenv(env);
}
}
else if(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;
}