用C写一个简单的shell解释器,可以执行简单的命令并传递参数,实现管道的功能
时间: 2023-06-23 14:08:45 浏览: 107
好的,以下是一个简单的shell解释器的示例代码,可以执行简单的命令并传递参数,同时支持管道功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define BUFFER_SIZE 1024
#define MAX_ARGS 64
#define MAX_PIPES 16
void execute(char *args[], int num_pipes);
int main() {
char buffer[BUFFER_SIZE];
char *args[MAX_ARGS];
int num_args = 0;
int num_pipes = 0;
int i;
// 读取命令行输入
while (1) {
printf("shell> ");
fgets(buffer, BUFFER_SIZE, stdin);
// 处理换行符
buffer[strcspn(buffer, "\n")] = '\0';
// 分割命令行参数
char *token = strtok(buffer, " ");
num_args = 0;
num_pipes = 0;
while (token != NULL) {
if (strcmp(token, "|") == 0) {
num_pipes++;
args[num_args] = NULL;
} else {
args[num_args] = token;
}
num_args++;
token = strtok(NULL, " ");
}
args[num_args] = NULL;
// 执行命令
execute(args, num_pipes);
}
return 0;
}
void execute(char *args[], int num_pipes) {
int i;
int pipe_fds[MAX_PIPES][2];
pid_t pid;
// 创建管道
for (i = 0; i < num_pipes; i++) {
if (pipe(pipe_fds[i]) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
}
// 执行命令
for (i = 0; i <= num_pipes; i++) {
if ((pid = fork()) == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// 子进程
if (i != 0) {
// 将前一个命令的输出重定向到管道写端
dup2(pipe_fds[i-1][0], STDIN_FILENO);
}
if (i != num_pipes) {
// 将当前命令的输出重定向到管道写端
dup2(pipe_fds[i][1], STDOUT_FILENO);
}
// 关闭所有无用的管道文件描述符
int j;
for (j = 0; j < num_pipes; j++) {
close(pipe_fds[j][0]);
close(pipe_fds[j][1]);
}
// 执行命令
execvp(args[i*2], &args[i*2]);
perror("execvp");
exit(EXIT_FAILURE);
} else {
// 父进程
if (i != 0) {
// 关闭前一个命令的输出
close(pipe_fds[i-1][0]);
}
if (i != num_pipes) {
// 关闭当前命令的输入
close(pipe_fds[i][1]);
}
// 等待子进程结束
int status;
waitpid(pid, &status, 0);
}
}
}
```
这个解释器可以在命令行中执行简单的命令,例如:
```
shell> ls
```
它也支持管道,例如:
```
shell> ls | grep c
```
这将列出当前目录下所有以 ".c" 结尾的文件。
相关推荐
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)