shell命令解析器三

/* ************************************************************************
 *       Filename:  main.c
 *    Description: 
 *        Version:  1.0
 *        Created:  2010年09月20日 11时47分58秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME ()
 *        Company: 
 * ************************************************************************/
#include"my_shell.h"
char *argv[20];
int main()
{
 while(1)
 {
  char cmd_buf[200]="";
  char cur_dir[50];
  int i = 0;
  getcwd(cmd_buf, sizeof(cmd_buf)); 
  printf("[%s@ %s]$",getenv("USER"),1+strrchr(cmd_buf, '/'));
  
 // printf("[%s@ ]$",getenv("USER"));//打印提示符号。
  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(infun(i-1, argv))
   continue;

  //处理外部命令
  if(fork()==0)  //创建子进程  调用execvp运行外部命令。
  {
   i=0;
   while(argv[i]!=NULL)
   {
    if( strcmp(argv[i],"|")==0)
    {
     my_pipe(i);
    }
    i++;
   } 
   execvp(argv[0],argv);  
   printf("command no found!/n");
   exit(1);
  }
  wait(NULL);  //父进程等待子进程结束。

 

/* ************************************************************************
 *       Filename:  my_pipe.c
 *    Description: 
 *        Version:  1.0
 *        Created:  2010年09月20日 11时47分58秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME ()
 *        Company: 
 * ************************************************************************/

#include "my_shell.h"
void my_pipe(int i)    
{
 pid_t pid;
 int pipe_fd[2];
 if(pipe(pipe_fd)<0)
 {
  perror("pipe"); 
  exit(1);
 }
 if((pid=fork())==0)
 {
   argv[i]=NULL;
   close(pipe_fd[0]);      //关掉管道的读端
   close(1);               
   dup2(pipe_fd[1],1);    //标准输出重定向到管道的写端
   execvp(argv[0],argv);        //
 }
 else
 {
  close(pipe_fd[1]);
  close(0);
  dup2(pipe_fd[0],0);        //标准输入重定向到管道的写端
  execvp(argv[i+1],argv+i+1);       //执行exec函数
   perror("execvp more");
 }
 printf("my_pipe error/n");
}

 }
 return 0;
}

/* ************************************************************************
 *       Filename:  shell_fun.c
 *    Description: 
 *        Version:  1.0
 *        Created:  2010年09月20日 12时36分54秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (),
 *        Company: 
 * ************************************************************************/
#include"my_shell.h"

 

/***************************************************
*函数名  :int cd_fun(int argc, char *argv[])
*功能描述 :cd 命令处理函数
***************************************************/
static char OLD_DIR[MAX_DIR]="";
int cd_fun(int argc, char *argv[])
{
 char *dir=argv[1];
 char buf[MAX_DIR]="";
 if(strcmp(argv[1], "-")==0) 
 {
  strcpy(buf,OLD_DIR);
  dir = buf;
 }
 else if(strcmp(argv[1], "~")==0)
 {
  dir = getenv("HOME");
 }
 getcwd(OLD_DIR,MAX_DIR);
 chdir(dir); //跳到相应的目录
 return 0;
}

/***************************************************
*函数名  :int exit_fun(int argc, char *argv[])
*功能描述 :exit 命令处理函数
***************************************************/
int exit_fun(int argc, char *argv[])
{
 printf("ByeBye!/n");
 exit(1);
}

/***************************************************
*函数名  :int test1_fun(int argc, char*argv[])
*功能描述 : test 命令处理函数
***************************************************/
int test1_fun(int argc, char*argv[])
{
 printf("this is a test fun!/n");
 return 0;
}

/***************************************************
*函数指针:用来指向内部命令的处理函数
***************************************************/
typedef int(*cmd_fun_t)(int argc, char *argv[]);

/* 内部命令结构体 */
typedef struct cmd_info
{
 char *cmd_name;   //内部命令名称
 cmd_fun_t fun;   //指向内部命令的处理函数
}CMD_STRUCT, pCMD_STRUCT;

/***************************************************
*内部命令及处理函数
***************************************************/
CMD_STRUCT cmd_list[]={
 {"cd", cd_fun},
 {"exit", exit_fun},
 {"test1", test1_fun}
};//定义一个结构体数组。

/***************************************************
* 函数功能:是否为内部命令,如果是内部命令并进行处理
* 参数:
*  int argc  :  参数个数
*  char *argv[]: 指向命令各个字段的指针数组
* 返回:
* 1 : 内部命令 
* 0 : 外部命令
*****************************************************/
int infun(int argc, char *argv[])
{
 int i = 0;
 int cmd_num = sizeof(cmd_list)/sizeof(CMD_STRUCT);//为三
 while(i<cmd_num)  //从第一个开始比较。
 {
  //判断是否为内部命令
  if(strcmp(cmd_list[i].cmd_name,argv[0])==0)
  { //如果是,则执行相应的处理函数
   cmd_list[i].fun(argc, argv);
   return 1;
  }
  i++;
 }
 return 0;
}

 

/* ************************************************************************
 *       Filename:  my_pipe.h
 *    Description: 
 *        Version:  1.0
 *        Created:  2010年09月20日 12时36分54秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (),
 *        Company: 
 * ************************************************************************/

#ifndef __MY_PIPE_INCLUDE_
#define __MY_PIPE_INCLUDE_
extern void my_pipe(int i);
#endif

 

/* ************************************************************************
 *       Filename:  my_shell.h
 *      Description: 
 *        Version:  1.0
 *        Created:  2010年09月20日 12时36分54秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (),
 *        Company: 
 * ************************************************************************/

#ifndef __MY_SHELL_INCLUDE_
#define __MY_SHELL_INCLUDE_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>
#include "my_pipe.h"
#include "shell_fun.h"


extern char *argv[20];
#endif

 

/* ************************************************************************
 *       Filename:  shell_fun.h
 *    Description: 
 *        Version:  1.0
 *        Created:  2010年9月20日 12时37分46秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (),
 *        Company: 
 * ************************************************************************/

#ifndef  _SHELL_FUN_H_
#define  _SHELL_FUN_H_

//是否为内部命令,如果是内部命令并进行处理
//参数:
//  int argc  :  参数个数
//  char *argv[]: 指向命令各个字段的指针数组
//返回:1(内部命令) 0(外部命令)
int infun(int argc, char *argv[]);
#define MAX_DIR 100
#endif   //_SHELL_FUN_H_

 

 

 ----------------------------------------------Makefile----------------------------------------------------------------------

#README:
#Use "make" to generate "mysh" without debug info
#Use "make dmysh" to generate "dmysh" with debug info

OBJECT=main.o  my_pipe.o shell_fun.o
OBJ=main.obj   my_pipe.obj shell_fun.obj
CC=gcc
CFLAG=-O2
DEBUG=-DDEBUG -g

mysh: $(OBJECT) my_shell.h
 $(CC) $(CFLAG) -o $@ $(OBJECT)

%.o:%.c
 $(CC) -c $(CFLAG) -o $@ $<
 
###########################################
#just for debug  
dmysh: $(OBJ) my_shell.h
 $(CC) $(CFLAG) $(DEBUG) -o $@ $(OBJ)

%.obj:%.c
 $(CC) -c $(CFLAG) $(DEBUG) -o $@ $< 
##########################################

.PHONY:clean
clean:
 @echo Clean...
 @-rm *.o *.obj mysh dmysh -f
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值