1、编写一个C程序 增加功能以使用户可以使用“&”操作符作为命令的结束符。一个以“&”结尾的命令应该与shell并发执行。 增加功能以使用户可以使用“<”和“>”作为文件名前缀来重定向stdin和stdout描述符。同样,允许用户使用管道操作符“|”来同时执行两个进程,并把第一个进程的stdout重定向为第二个进程的stdin。

时间: 2023-09-17 20:08:41 浏览: 46
以下是一个简单的C程序,可以实现您的要求: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #define MAX_ARGS 10 // 最大参数数目 #define MAX_ARG_LEN 50 // 最大参数长度 int execute(char **args, int background, int input, int output, int pipe_to); char **parse_input(char *input) { char **args = malloc(MAX_ARGS * sizeof(char *)); char *arg = strtok(input, " \t\n"); // 使用空格、制表符和换行符作为分隔符 int i = 0; while (arg != NULL) { args[i++] = arg; arg = strtok(NULL, " \t\n"); } args[i] = NULL; // 参数列表以NULL结尾 return args; } int main() { char input[100]; int should_run = 1; while (should_run) { printf("shell> "); fflush(stdout); fgets(input, sizeof(input), stdin); // 从标准输入读取用户输入 input[strlen(input) - 1] = '\0'; // 去除字符串末尾的换行符 // 检查是否以“&”结尾,表示后台执行 int background = 0; if (input[strlen(input) - 1] == '&') { background = 1; input[strlen(input) - 1] = '\0'; } // 检查是否有输入重定向 int input_fd = 0; char *input_file = strstr(input, "<"); if (input_file != NULL) { *input_file = '\0'; // 将输入文件名与命令分开 input_file += 2; // 跳过“< ”前缀 input_fd = open(input_file, O_RDONLY); if (input_fd == -1) { perror("open"); continue; } } // 检查是否有输出重定向 int output_fd = 0; char *output_file = strstr(input, ">"); if (output_file != NULL) { *output_file = '\0'; // 将输出文件名与命令分开 output_file += 2; // 跳过“> ”前缀 output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (output_fd == -1) { perror("open"); continue; } } // 检查是否有管道 int pipe_fd[2] = {0, 0}; char *pipe_to = strstr(input, "|"); if (pipe_to != NULL) { *pipe_to = '\0'; // 将第一个命令与管道符分开 pipe_to += 2; // 跳过“| ”前缀 if (pipe(pipe_fd) == -1) { perror("pipe"); continue; } } // 解析用户输入,生成参数列表 char **args = parse_input(input); // 执行命令 int status = execute(args, background, input_fd, output_fd, pipe_fd[1]); if (status == -1) { printf("Error executing command.\n"); } // 关闭文件描述符 if (input_fd != 0) { close(input_fd); } if (output_fd != 0) { close(output_fd); } if (pipe_fd[0] != 0) { close(pipe_fd[0]); } if (pipe_fd[1] != 0) { close(pipe_fd[1]); } // 释放内存 int i = 0; while (args[i] != NULL) { free(args[i]); i++; } free(args); } return 0; } int execute(char **args, int background, int input, int output, int pipe_to) { pid_t pid = fork(); if (pid == -1) { perror("fork"); return -1; } else if (pid == 0) { // 子进程 // 处理输入重定向 if (input != 0) { if (dup2(input, STDIN_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } } // 处理输出重定向 if (output != 0) { if (dup2(output, STDOUT_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } } // 处理管道 if (pipe_to != 0) { if (dup2(pipe_to, STDOUT_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } close(pipe_to); } // 执行命令 if (execvp(args[0], args) == -1) { perror("execvp"); exit(EXIT_FAILURE); } } else { // 父进程 // 如果命令以“&”结尾,不等待子进程执行完毕 if (!background) { int status; waitpid(pid, &status, 0); return status; } } return 0; } ``` 该程序使用了标准C库提供的函数和系统调用来实现输入重定向、输出重定向、管道和后台执行等功能。当用户输入一条命令时,程序会解析命令,生成参数列表,并在子进程中执行该命令。如果命令以“&”结尾,子进程将在后台执行,父进程不会等待其完成。如果命令包含输入重定向、输出重定向或管道,程序会相应地修改文件描述符。

相关推荐

最新推荐

recommend-type

回文判断,回文判断,试编写一个算法,判断依次读入的一个以@为结素符的字母序列

回文判断,试编写一个算法,判断依次读入的一个以@为结素符的字母序列。自己找到的,希望帮到你们。
recommend-type

EDA/PLD中的Verilog HDL移位操作符

移位操作符有:* &gt; (右移) 移位操作符左侧操作数移动右侧操作数表示的次数,它是一个逻辑移位。空闲位添0补位。如果右侧操作数的值为x或z, 移位操作的结果为x。假定:reg [0:7] Qreg;. . .Qreg = 4'b0111;那么:Qreg...
recommend-type

关于__Federico Milano 的电力系统分析工具箱.zip

1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
recommend-type

mlab-upenn 研究小组的心脏模型模拟.zip

1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
recommend-type

混合图像创建大师matlab代码.zip

1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

:YOLOv1目标检测算法:实时目标检测的先驱,开启计算机视觉新篇章

![:YOLOv1目标检测算法:实时目标检测的先驱,开启计算机视觉新篇章](https://img-blog.csdnimg.cn/img_convert/69b98e1a619b1bb3c59cf98f4e397cd2.png) # 1. 目标检测算法概述 目标检测算法是一种计算机视觉技术,用于识别和定位图像或视频中的对象。它在各种应用中至关重要,例如自动驾驶、视频监控和医疗诊断。 目标检测算法通常分为两类:两阶段算法和单阶段算法。两阶段算法,如 R-CNN 和 Fast R-CNN,首先生成候选区域,然后对每个区域进行分类和边界框回归。单阶段算法,如 YOLO 和 SSD,一次性执行检
recommend-type

ActionContext.getContext().get()代码含义

ActionContext.getContext().get() 是从当前请求的上下文对象中获取指定的属性值的代码。在ActionContext.getContext()方法的返回值上,调用get()方法可以获取当前请求中指定属性的值。 具体来说,ActionContext是Struts2框架中的一个类,它封装了当前请求的上下文信息。在这个上下文对象中,可以存储一些请求相关的属性值,比如请求参数、会话信息、请求头、应用程序上下文等等。调用ActionContext.getContext()方法可以获取当前请求的上下文对象,而调用get()方法可以获取指定属性的值。 例如,可以使用 Acti
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。