Linux C语言 shell
程序员文章站
2022-03-04 15:52:57
...
#include "wrapper.h"
#include <time.h>
int MAXARGS=10;
int parseline(char *buf, char **argv) {
char *delim; /* 指向第1个分隔符 */
int argc; /* 字符串数组args中命令行参数个数 */
int bg; /* 后台作业 */
buf[strlen(buf)-1] = ' '; /* 用空格替换行末换行符 */
while (*buf && (*buf == ' ')) /* 删除行首空格 */
buf++; /* 创建 argv数组 */
argc = 0;
while ((delim = strchr(buf, ' '))) {
argv[argc++] = buf; *delim = '\0';
buf = delim + 1;
while (*buf && (*buf == ' ')) /* 忽略空格,查找下一个参数起始位置 */
buf++;
}
argv[argc] = NULL;
if (argc == 0) /* 忽略空行*/
return 1; /* 命令是否应在后台执行 */
if ((bg = (*argv[argc-1] == '&')) != 0)
argv[--argc] = NULL;
return bg;
}
void execute(char *cmdline) {
char *argv[MAXARGS]; /* execve()参数表 */
char buf[MAXLINE]; /* 保存修改后的命令行 */
int bg; /* 是否在后台执行 */
int fd;
pid_t pid; /* 子进程PID */
strcpy(buf, cmdline);
bg = parseline(buf, argv); /* 解析命令行 */
if (argv[0] == NULL) return; /* 如果第1个参数为空,则忽略命令 */
if (!builtin_command(argv))
{ if ((pid = fork()) == 0)
{ /* 创建子进程 */
if(!strcmp(argv[3],">>")||!strcmp(argv[3],">")){
fd=open(argv[4],O_RDWR,0); /*重定向功能*/
dup2(fd,1); /*execvp的输出在1而不在0,把1指向fd*/
}
if (execvp(argv[0], argv) < 0) { printf("%s: Command not found.\n", argv[0]);
close(fd); /*记得保存*/ /*agrv[0][1]...是解析好的各参数*/ /*execvp不用bin目录的路径*/
exit(0);
}
}if (!bg) { /* 前台执行 */ int status;
if (waitpid(pid, &status, 0) < 0) perror("waitpid error");
}
else printf("%d %s", pid, cmdline);
}
return;
}
int builtin_command(char **argv) {
if (!strcmp(argv[0], "exit")) /* 内置命令exit */ exit(0);
if (!strcmp(argv[0], "logout")) /* 内置命令logout */ exit(0);
if (!strcmp(argv[0], "&")) /* 忽略由&开始的命令串 */
return 1;
return 0; /* 非内置命令 */
}
int main() {
char cmdline[MAXLINE]; /* 命令行缓冲区 */
while (1) { printf("%% "); /*一个百分号是转义的,得两个*/
fgets(cmdline, MAXLINE, stdin); /* 读取命令行 */
if (feof(stdin)) exit(0); execute(cmdline);
/* 执行命令 */ }
}
想说的都在注释里
上一篇: CPU管理与多进程图像