今天开始做shell命令解释器项目,要求:
1、 能够执行外部程序命令,命令可以带参数;
2、 能够执行fg、bg、cd、history、exit等内部命令;
3、 使用管道和输入输出重定向;
4、 支持前后台作业,提供作业控制功能,包括打印作业的清单,改变当前运行作业的前/后台状态,以及控制作业的挂起、中止与继续运行;
5、 使用Make工具建立工程;
6、 使用调试器gdb来调试程序;
整个过程分为8个步骤,首先写最基础的框架:
需要完成的内容如下:
1) 命令解释器首先是一个死循环。
2) 打印一个命令提示符。
3) 取得命令行输入放在数组里面,不要求命令带参数。可以getc()、fgets()、scanf()等。
4) 如果用fgets()的话,取得的字符串包括最后输入的换行符,故要去掉命令字符串末尾的“/n”,变成“/0”。
5) 创建一个子进程,调用exec执行命令。
6) 父进程调用waitpid()等待子进程的退出,然后进入下一次循环。
/* ************************************************************************
* Filename: main.c
* Description:
* Version: 1.0
* Created: 2010年9月19日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME (),
* Company:
* ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>
int main(int argc, char *argv[])
{
while(1)
{
char cmd_buf[200]="";
char *argv[20]={NULL};
int i = 0;
getcwd(cmd_buf, sizeof(cmd_buf)); //获取当前目录保存在字符数组当中。
printf("[%s@ %s]$",getenv("USER"),1+strrchr(cmd_buf, '/')); //打印提示符号。
fgets(cmd_buf, sizeof(cmd_buf), stdin); //获取字符串
cmd_buf[strlen(cmd_buf)-1]='/0'; //把最后一位'/n'变成字符串结束标志'/0'
if(cmd_buf[0]=='/0')
continue; //如果是输入回车的话,继续while循环
argv[i++]=strtok(cmd_buf, " ");
while((argv[i++]=strtok(NULL," "))!=NULL); //字符串按空格切割
if(fork()==0) //创建子进程 调用execvp运行外部命令。
{
execvp(argv[0],argv);
printf("command no found!/n");
exit(1);
}
wait(NULL); //父进程等待子进程结束。
}
return 0;
}
---------------------------------Makefile-----------------------------------
OBJ=main.o
CC=gcc
CFLAGS=-Wall
mysh:$(OBJ)
$(CC) $^ -o $@ $(CFLAGS)
%.o:%.c
$(CC) -c $^ -o $@ $(CFLAGS)
clean:
@-rm mysh *.o
@echo Cleanning...