实验内容:扩充版本 0 内核,在系统启动时直接提供命令解释器功能(不运行硬盘上的命令解释器),即不断接收用户输入的命令并正确给出反馈。要求该命令解释器既支持内部命令 cd、sync、exit、cat;也支持外部命令,即可以接收 cp、vi 等命令,然后执行硬盘上相应的可执行程序。给出完整思路和完整代码
时间: 2023-11-22 15:54:09 浏览: 42
思路:
1. 在内核中加入命令解释器功能,即通过输入命令来执行对应的操作。
2. 实现内部命令:cd、sync、exit、cat
3. 实现外部命令:cp、vi,通过解析用户输入的命令来判断需要执行哪个命令。
4. 处理用户输入的命令,解析出命令名和参数,并将命令交给相应的处理函数处理。
完整代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1024
#define MAX_ARGC 64
#define MAX_PATH 256
char cmd[MAX_LEN]; // 存放用户输入的命令
char path[MAX_PATH]; // 存放当前路径
// 内部命令处理函数
int cd(char *argv[]);
int sync();
int exit_shell();
int cat(char *argv[]);
// 外部命令处理函数
int cp(char *argv[]);
int vi(char *argv[]);
// 命令处理函数数组
struct command {
char *name;
int (*func)(char *[]);
} commands[] = {
{"cd", cd},
{"sync", sync},
{"exit", exit_shell},
{"cat", cat},
{"cp", cp},
{"vi", vi},
{NULL, NULL}
};
// 解析用户输入的命令
int parse_command(char *cmd, char *argv[]) {
int argc = 0;
char *p = strtok(cmd, " ");
while (p != NULL && argc < MAX_ARGC - 1) {
argv[argc++] = p;
p = strtok(NULL, " ");
}
argv[argc] = NULL;
return argc;
}
// 查找命令处理函数
int find_command(char *name, struct command commands[]) {
for (int i = 0; commands[i].name != NULL; i++) {
if (strcmp(name, commands[i].name) == 0) {
return i;
}
}
return -1;
}
// 执行命令
int execute_command(char *cmd) {
char *argv[MAX_ARGC];
int argc = parse_command(cmd, argv);
if (argc == 0) {
return 0;
}
int index = find_command(argv[0], commands);
if (index == -1) {
printf("%s: command not found\n", argv[0]);
return -1;
}
return commands[index].func(argv);
}
// 内部命令处理函数:cd
int cd(char *argv[]) {
if (argv[1] == NULL) {
printf("usage: cd path\n");
return -1;
}
if (chdir(argv[1]) == -1) {
printf("cd: %s: No such file or directory\n", argv[1]);
return -1;
}
getcwd(path, MAX_PATH);
return 0;
}
// 内部命令处理函数:sync
int sync() {
printf("sync\n");
return 0;
}
// 内部命令处理函数:exit
int exit_shell() {
printf("exit\n");
exit(0);
}
// 内部命令处理函数:cat
int cat(char *argv[]) {
if (argv[1] == NULL) {
printf("usage: cat file\n");
return -1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("cat: %s: No such file or directory\n", argv[1]);
return -1;
}
char buf[MAX_LEN];
while (fgets(buf, MAX_LEN, fp) != NULL) {
printf("%s", buf);
}
fclose(fp);
return 0;
}
// 外部命令处理函数:cp
int cp(char *argv[]) {
if (argv[1] == NULL || argv[2] == NULL) {
printf("usage: cp src_file dest_file\n");
return -1;
}
FILE *src_fp = fopen(argv[1], "r");
if (src_fp == NULL) {
printf("cp: %s: No such file or directory\n", argv[1]);
return -1;
}
FILE *dest_fp = fopen(argv[2], "w");
if (dest_fp == NULL) {
printf("cp: %s: No such file or directory\n", argv[2]);
return -1;
}
char buf[MAX_LEN];
while (fgets(buf, MAX_LEN, src_fp) != NULL) {
fprintf(dest_fp, "%s", buf);
}
fclose(src_fp);
fclose(dest_fp);
return 0;
}
// 外部命令处理函数:vi
int vi(char *argv[]) {
printf("vi: not implemented yet\n");
return 0;
}
int main() {
getcwd(path, MAX_PATH); // 获取当前路径
printf("Welcome to ChitShell!\n");
while (1) {
printf("%s $ ", path);
fgets(cmd, MAX_LEN, stdin);
if (strlen(cmd) > 0 && cmd[strlen(cmd) - 1] == '\n') {
cmd[strlen(cmd) - 1] = '\0'; // 去掉换行符
}
execute_command(cmd);
}
return 0;
}
```