实验目的 实现一个模拟的shell 实验内容 编写三个不同的程序:cmd1.c, cmd2.c, cmd3.c,每个程序输出一句话,分别编译成可执行文件cmd1, cmd2, cmd3。然后再编写一个程序,模拟shell程序的功能,能根据用户输入的字符串(表示相应的命令名),去为相应的命令创建子进程并让它去执行相应的程序,而父进程则等待子进程的结束,然后再等待接收下一条命令。如果接收到的命令为exit,则父进程结束,如果接收到无效命令,则显示”command not found”,继续等待。
时间: 2023-12-03 13:44:05 浏览: 162
操作系统实验报告 shell程序
3星 · 编辑精心推荐
以下是一个简单的实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX_CMD_LEN 1024
int main() {
char cmd[MAX_CMD_LEN];
while (1) {
printf("shell> ");
fgets(cmd, MAX_CMD_LEN, stdin);
cmd[strcspn(cmd, "\n")] = '\0'; // 去掉末尾的换行符
if (strcmp(cmd, "exit") == 0) {
break;
}
int pid = fork();
if (pid == -1) {
perror("fork error");
exit(1);
}
if (pid == 0) {
// 子进程
char *args[] = {cmd, NULL};
execv(cmd, args);
perror("execv error");
exit(1);
} else {
// 父进程
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
int exit_status = WEXITSTATUS(status);
if (exit_status != 0) {
printf("command '%s' exited with status %d\n", cmd, exit_status);
}
} else {
printf("command '%s' terminated abnormally\n", cmd);
}
}
}
printf("bye!\n");
return 0;
}
```
在该程序中,我们首先定义了一个 char 数组 `cmd` 用于存储用户输入的命令。然后在一个无限循环中,不断提示用户输入命令,读入命令后去掉末尾的换行符。如果输入的命令为 "exit",则退出循环,结束程序。
对于其他命令,我们首先调用 `fork()` 函数创建一个子进程。在子进程中,我们调用 `execv()` 函数来执行用户输入的命令。如果 `execv()` 函数执行成功,子进程就会被替换成新的程序,而不会继续执行原来的程序。
在父进程中,我们调用 `waitpid()` 函数等待子进程的结束。如果子进程正常结束,我们检查其返回状态,如果返回值不为 0,则显示该命令退出时的状态码。如果子进程异常结束,我们也会显示一条错误信息。
需要注意的是,在调用 `execv()` 函数时,需要将命令名和参数分开传递。在本例中,我们将命令名放在 `args` 数组的第一个元素中,将参数设置为 `NULL`。这样做的原因是,`execv()` 函数会将第一个参数作为新程序的名称,然后在该程序中获取参数列表。如果我们将整个命令字符串都传递给 `execv()` 函数,那么新程序将无法正确解析参数。
阅读全文