一个简易的shell
来源:互联网 发布:linux 查看路由 编辑:程序博客网 时间:2024/05/16 07:56
《Unix系统》课程大作业,支持不定长度参数、管道和I/O重定向。暂不支持正则和cd命令。以后有时间再增加更多内容。
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<pwd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#define MAXLEN 1000void swap(int *a, int *b){ int t = *a; *a = *b; *b = t;}int parse_cmd(char *content, int *argc, char *argv[]){ char *p; int num = 0; if (argc == NULL || argv == NULL) return -1; p = content; argv[num++] = p; while (*p) { if ((*p == '\r') || (*p == '\n')) { *p = '\0'; break; } if (*p == '|' ) { *p = 0; p++; argv[num++] = p; continue; } p++; } *argc = num; return 0;}int parse_parameter(char *content, int *argc, char *argv[]){ char *p; int num = 0; int start = 1; if (argc == NULL || argv == NULL) return -1; p = content; while (*p) { if ((*p == '\r') || (*p == '\n')) { *p = '\0'; break; } if ((*p == ' ') || (*p == '\t') || (*p == '\'') || (*p == '\"')) { start = 1; *p = '\0'; p++; continue; } if (start) { argv[num++] = p; start = 0; } p++; } argv[num++] = 0; *argc = num; return 0;}void work(int argc, char *argv[]){ if (argc > 3) { if (strcmp(argv[argc - 3], "<") == 0) { int file = open(argv[argc - 2], O_RDWR | O_NONBLOCK); if (file < 0) { printf("Can not open this file\n"); return; } argv[argc - 2] = argv[argc - 3] = 0; dup2(file, 0); close(file); dup2(0, 0); } else if (strcmp(argv[argc - 3], ">") == 0) { int file = open(argv[argc - 2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (file < 0) { printf("Can not open this file\n"); return; } argv[argc - 2] = argv[argc - 3] = 0; dup2(file, 1); close(file); dup2(1, 1); } } if (execvp(argv[0], argv) < 0) { printf("Command failed\n"); }}void do_pipe(int depth, int cmd_num, char *cmds[]){ int argc = 0; int pid; char *argv[MAXLEN]; parse_parameter(cmds[depth], &argc, argv); if (depth == cmd_num - 1) { pid = fork(); if (pid == 0) work(argc, argv); wait(pid, NULL, 0); return; } int fd[2]; pipe(fd); pid=fork(); if (pid == 0) { dup2(fd[1], 1); close(fd[0]); close(fd[1]); work(argc, argv); } dup2(fd[0], 0); close(fd[0]); close(fd[1]); wait(pid, NULL, 0); do_pipe(depth + 1, cmd_num, cmds);}int main(){ struct passwd* pwd; char host[MAXLEN]; char cwd[MAXLEN]; char content[MAXLEN]; int argc = 0; int cmd_num = 0; char *cmds[MAXLEN]; char *argv[MAXLEN]; memset(content, 0, sizeof(content)); printf("Myshall\n"); printf("please input \"exit\" or \"quit\" to exit\n"); while (1) { pwd = getpwuid(getuid()); gethostname(host, MAXLEN); getcwd(cwd, MAXLEN); printf("%s@%s:%s$ ", pwd -> pw_name, host, cwd); while(strlen(content) == 0) fflush(stdin),gets(content); parse_cmd(content, &cmd_num, cmds); if (strcmp(cmds[0], "exit") == 0 || strcmp(cmds[0], "quit") == 0) break; int pid = fork(); if (pid == 0) { do_pipe(0, cmd_num, cmds); return 0; } wait(pid, 0, NULL); memset(content, 0, sizeof(content)); } return 0;}
阅读全文
0 0
- 一个简易的shell
- 自己动手制作一个简易的shell
- 简易的shell ---- MOS 的一个小练习题
- 一个Linux中用于监控的简易shell脚本
- 一个Linux中用于监控的简易shell脚本
- 一个Linux中用于监控的简易shell脚本
- Shell,我的简易实现!
- 一个简易的记事本
- 一个简易的屏幕保护程序
- 一个简易的计算器
- 一个简易的HashMap
- 一个简易的计算器
- 一个简易的指南针
- 一个简易的allocator
- 简易Shell
- Linux下实现简易的shell
- 一个简易计算器的实现
- 一个简易的数控电源
- 求两个字符串的最长公共子串
- C/C++ 笔试、面试题目大汇总
- cookie 和 session
- 深入学习Oracle分区表及分区索引
- Luogu 八皇后
- 一个简易的shell
- stm8——串口printf的实现
- SpringMVC01
- zzuli 2132
- 使用fiddler抓包手机HTTP请求
- 欢迎使用CSDN-markdown编辑器
- 奇数前进
- 二值图像处理闭运算
- 机器学习实现bayes