shell能手帮哈手啦~``

shell能手帮哈手啦~``

实现一个简单的shell
只要实现4个命令,我刚接触,只晓得一点原理,自己写根本写不出嘛
以下四个命令
Environ列出所以环境变量字符串的设置(类似与Unix系统下的env命令)
Echo<内容>显示echo后的内容且换行
Help简短概要的输出你的shell的使用方法和基本功能
Jobs输出shell当前的一系列子进程,必须提供子进程的命名和PID号
Quit,exit,bye退出shell。


谁能帮哈我啦,万分感谢,到网上看类似的代码就几十行,希望哪为好心人帮我写一下,万分感谢,qq币奉上啦!!!!!      
点嘛没人帮手啦??好郁闷咯!!      
good good study, day day up      
我也知道这个道理,可是刚学怎么写的出,现在的老师真的厉害,我没的办法才出此下策,谁真的能帮下我忙啊      
等到凌晨3点也没人帮忙啊,郁闷哦      
[QUOTE=guanguan3]等到凌晨3点也没人帮忙啊,郁闷哦[/QUOTE]
精神可嘉
何苦干等着, 一天的时间你就是现学也搞定了      
我学了一天了啊,可惜没搞的很懂,知道是知道怎么回事了,就是不知道下手啊      
不知道这个对不对,在别人的指点下写的
#define SIZE 100
#define BUFFSIZE 200
#define BUFFERSIZE  1024
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/wait.h>
#include<math.h>
#include<malloc.h>
#include<signal.h>
#include<stdlib.h>
   //*************************************** **********************/
  typedef struct SH_HISTORY   //*用循环链表存储用过的SH_HISTORY命令 */
{   
          int start;
          int end;
          char command_his[SIZE][100];
  }SH_HISTORY;
typedef struct NODE        // /*把作业用链表保存起来*/   
{
         pid_t pid;   //*进程号*/
         char cmd[100]; // /*命令字符*/
         char state[10];  //*状态*/
         struct NODE *next;  //*指向下一接点的指针*/
        }NODE;
  char *envpath[10],buff[BUFFSIZE],*input=NULL;
  pid_t pid1=0;
  int  sig_flag=0,sig_z=0;
  SH_HISTORY sh_his;
NODE *head,*end;
//*******************声明程序中用到的函数****************************/
             int found_cmd(); //*查找命令函数*/
         int getline();  //*读取一行的函数*/   
             void init_environ();  //*初始化环境变量*/
             void history_add(); //*记录history命令的函数*/
             void command_history();//*显示history命令的函数*/
void command_cd();//*处理cd命令的函数*/
             void command_jobs();//*处理jobs命令的函数*/
void setflag();//*将标志位置1的函数*/
               void getenviron();//*初始化查找路径的函数*/
         void ctrl_z(); //*处理用户按下ctrl-z是时的函数*/  
             void command_echo();//*处理echo命令的函数*/
             void dele_node();//*向jobs命令的链表中删除节点的函数*/
         void add_node();//*向jobs命令的链表中增加节点的函数*/
void print_help(); //*处理help命令的函数*/
          void command_mkdir(); //*建立目录的函数*/
          void command_rmdir();//*撤销目录的函数*/
void command_environ(); //*处理environ命令的函数*/  
//*******************************main************************************/
main()
{
              init_environ();  //*初始化环境变量,将查找路径置于envpath[]中*/
          while(1)
{
                  char ch,*argment[20];
                  int i=0,j=0,k=0,is_pr=0,is_bg=0,input_len=0,pid=0,path,status=0,tmp=0;
          //        ***************************设置signal信号*************************/
        struct sigaction action;
                  action.sa_sigaction=dele_node;
                  sigfillset(&action.sa_mask);
                  action.sa_flags=SA_SIGINFO;
                  sigaction(SIGCHLD,&action,NULL);
                  signal(SIGTSTP,ctrl_z);
          //********************打印提示符**********************/
            path=get_current_dir_name();
            printf("<shell@%s> ",path);
           //***********获取用户输入***************/
          while((ch=getchar())==' '||ch=='\t'||ch==EOF) //*跳过空格等无用信息*/
          if(ch=='\n')  continue; //*输入为空时结束本次循环,打印提示符*/
                   while(ch!='\n')
{       
                           buff[input_len++]=ch;
                           ch=getchar();
                    }
                  buff[input_len]='\0'; //*加上串结束符*/
         //*分配动态存储空间,将命令从缓冲区复制到input中*/
                  input=(char *)malloc(sizeof(char)*(input_len+1));
                  strcpy(input,buff);      // *将命令复制到input中*/
            // ******************************解析指令**************************/
          //***************普通命令****************/
                   if(is_pr==1) continue;//*如果is_pr==1,则执行普通命令,否则,执行管道命令*/
                           for(i=0,j=0,k=0;i<input_len+1;i++)
{
                             if(input==' '||input=='\0')  ///* 清除空格和结束符*/
                                   {
                                            if(j==0) //*略去连在一起的多个空格*/
                                                    continue;
                                            else
{
                                                    buff[j++]='\0';   
                                            argment[k]=(char *)malloc(sizeof(char)*j);
                                            strcpy(argment[k++],buff);//*将指令或参数复制到argment中*/
                                                   j=0;
                                         }
                                   }
                                           else{  //*如果字符串最后是&,将后台命令标志置1*/
                                                     if(input=='&'&&input=='\0')
{
                                                           is_bg=1;
                                                           continue;
                                                   }
                                                   buff[j++]=input;
                                             }
                    }
         
// ***************************内部命令****************************/
   if(strcmp(argment[0],"environ")==0||strcmp(argment[0],"en")==0)
{
         history_add(input);
         command_environ();
         free(input);
         continue;
     }  
   if(strcmp(argment[0],"rmdir")==0)
{  
         history_add(input);
         for(i=6,j=0;i<=input_len;i++)
                    buff[j++]=input;
                    buff[j]='\0';
                    argment[1]=(char *)malloc(sizeof(char)*j);
                    strcpy(argment[1],buff);
             command_rmdir(argment[1]);
         free(input);
                    continue;
         }  
  
if(strcmp(argment[0],"mkdir")==0)
{  
            history_add(input);
            for(i=6,j=0;i<=input_len;i++)
                       buff[j++]=input;
                       buff[j]='\0';
                       argment[1]=(char *)malloc(sizeof(char)*j);
                       strcpy(argment[1],buff);
                command_mkdir(argment[1]);
              free(input);
                         continue;
            }  
if(strcmp(argment[0],"help")==0)
{  
           history_add(input);
               print_help();
           free(input);
                      continue;
          }
// *********exit,bye,quit,退出*************/           
   if(strcmp(argment[0],"exit")==0||strcmp(argment[0],"quit")==0||strcmp(argment[0],"bye")==0) {
                    history_add(input);
            printf("bye bye!\n");
                    free(input);
             exit(0);
            break;
      }
   // *************history命令,显示history数组中保存的历史命令************/     
if(strcmp(argment[0],"history")==0)
{
               history_add(input);
               command_history();
               free(input);
         continue;
      }
   //*********echo命令, 显示输入过的字符串***************/
     if(strcmp(argment[0],"echo")==0){      
          history_add(input);
          for(i=0;i<=input_len;i++)
{
               if(input==' ')
                break;
            }
                    i++;
                   for(;i<=input_len;i++)
                   buff[j++]=input;
                   buff[j]='\0';
                   argment[1]=(char *)malloc(sizeof(char)*j);
                    strcpy(argment[1],buff);
                   command_echo(argment[1]);
                    free(input);
                   continue;
        }
/**********************************************/
     if(strcmp(argment[0],"cd")==0){                                    
              history_add(input);
           for(i=3,j=0;i<=input_len;i++)
                    buff[j++]=input;
                    buff[j]='\0';
                    argment[1]=(char *)malloc(sizeof(char)*j);
                    strcpy(argment[1],buff);
                    command_cd(argment[1]);
                    free(input);
                    continue;
           }
/********************************************/
   if(strcmp(argment[0],"jobs")==0){
                   history_add(input);
                   command_jobs();
                   free(input);
                   continue;
          }
//*********寻找命令文件**********/          
        if(is_pr==0)
{         
argment[k]=(char *)malloc(sizeof(char));
                  argment[k]=NULL;
                  if(found_cmd(argment[0])==0)
{
                          printf("This is an inavilable command!\n");
                          for(i=0;i<=k;i++){
                          free(argment);
                          continue;
                }
                 }                              
                  history_add(input);         
//************** 执行命令*****************/
      if((pid=fork())==0){       /*子进程*/
                            while(sig_flag==0)
                            signal(SIGUSR1,setflag);
                           sig_flag=0;
                            execv(buff,argment);
                      }
      else{
                    pid1=pid;   
                    add_node(input,pid1);
                   kill(pid,SIGUSR1);
                    pid1=0;
              waitpid(pid,&status,0);
                 }
      for(i=0;i<k;i++)
                     free(argment);
                     free(input);
           }       
   }       
}
/***********************主程序完成********************/
/*************函数定义*****************/        
void init_environ()
{
                 int fd,n,i;
                 char buff[80];
                 if((fd=open("sh_profile",O_RDONLY,660))==-1)
{
                         printf("init wrong!");
                         exit(1);
                while(n=getline(fd,buff))
                        getenviron(n,buff);
                        sh_his.start=0;
                        sh_his.end=0;
                        head=end=NULL;
                  }
//***************查找命令文件的函数********************************/
int found_cmd(char *cmd)
{
        int k=0;
        while(envpath[k]!=NULL){ //*查找路径已在程序初始化时设定在envpath中*/
                strcpy(buff,envpath[k]);
                strcat(buff,cmd);
                if(access(buff,F_OK)==0) //*文件被找到*/
                return 1;
                                        k++;
                                }
                                return 0;
        }
/********************************************************/
void history_add(char *inputcmd)
{
                    sh_his.end=(sh_his.end+1)%SIZE;  //*end前移一位*/
                   if(sh_his.end==sh_his.start)  //*end和 start同指向同一数组*/
                   sh_his.start=(sh_his.start+1)%SIZE; //*start前移一位*/
                   strcpy(sh_his.command_his[sh_his.end],inputcmd);
              //*将命令复制到指向end的数组中*/

        }
               
//*************************command-history *************************************/
void command_history()
{
         int i,count=0;
         if(sh_his.start==sh_his.end) //*循环数组为空*/
                 return;
else if(sh_his.start<sh_his.end)
{
            printf("id         command     \n");
                         for(i=sh_his.start+1;i<sh_his.end;i++)
             //*显示history命令数组中start+1到end个命令*/
                         {       
                                 printf("%d\t%s\n",count,sh_his.command_his);
                                  count++;  
                         }
         }       
        else {     
                printf("id          command     \n");
                                 for(i=sh_his.start+1;i<SIZE;i++)
             //*显示history命令数组中start+1到SIZE个命令*/

{
                                     printf("%d\t%s\n",count,sh_his.command_his);
                                     count++;
                                   }
                            for(i=0;i<sh_his.end;i++)   /*显示0~end个命令 */
                                  {
                                     printf("%d\t%s\n",count,sh_his.command_his);
                                     count++;
                                  }
                   }
}
/************************ *********************************/
void command_cd  (char *route)
{
                 if(route!=NULL)//*路径不为空*/
            if(chdir(route)<0) //*系统调用chdir函数,达到改变当前路径的目的*/
                printf("%s file error or didn't exist!\n",route);
     }
/**************************command-jobs**************************************/
void command_jobs()
{
    NODE *p;
    int i=1;
    p=head;
   if(head!=NULL)
{
       printf("id    pid    state     command\n");   
       printf("%d   %d   %s\t   %s \n",i,p->pid,p->state,p->cmd);
       i++;
       p=p->next;
    }
else
  printf("no process!\n");
}
/**************************add_node***********************************/
void add_node(char *input_cmd,int node_pid)
{
         NODE *p;
         p=(NODE *)malloc(sizeof(NODE));
         p->pid=node_pid;
         strcpy(p->cmd,input_cmd);
         strcpy(p->state,"running");
         p->next=NULL;
         if(head==NULL)
{
                 head=p;
                 end=p;
      }
        else
{
                end->next=p;
                end=p;
                 
        }
}
//************** dele_node *************************/
  void dele_node(int sig,siginfo_t *sif)
{
            NODE *q,*p;
            int id;
            if(sig_z==1)
                  {
                    sig_z=0;
                    return;
              }
         id=sif->si_pid;
         p=q=head;
         if(head==NULL)
                 return;
                 while(p->pid!=id&&p->next!=NULL)
{
                         p=p->next;
                         if(p->pid!=id)
                           return;
                     if(p==head)
                     head=head->next;
                    else
{
                            while(q->next!=p)
                            q=q->next;
                             if(p==end)
{
                                   end=q;
                                   q->next=NULL;
                             }
                          else q->next=p->next;       
                    }
                    free(q);
                 }
        }
/****************setflag*************************/
void setflag()
{
         sig_flag=1;
}
/******************getline**************************/       
int getline(int fd,char *buf)
{
                 int i=0;
                 char c;
                 while(read(fd,&c,1))
{
             buf[i++]=c;
             if(c=='\n')
{
                     buf[i-1]='\n';
                    return i;
              }
         }
        return i;
   }
/***********************getenviron****************************/
   void getenviron(int n,char *s)
{
             int i=0,count=0,k=0;
      char c,buff1[80],*p;
      while((c=s)!='=')
      buff1[i++]=c;
    buff1[i++]='\0';
   if(strcmp(buff1,"ATH")==0)
{
while(s!='\0')
{
                   if(s==':')
{
                           buff1[count++]='/';
                           buff1[count]='\0';
                           p=(char *)malloc(strlen(buff1)+1);
                           strcpy(p,buff1);
                           envpath[k++]=p;
                           envpath[k]=NULL;
                           count=0;
                           i++;
                     }
else
{
                           buff1[count]=s;
                           count++;
                           i++;
                    }
            }
  }
  else
    fprintf(stderr,"no match\n");
  }
/******************ctrl-z***********************************/
void ctrl_z()
{
          NODE *p;
          int i=1;
          if(pid1==0) return;
        if(head!=NULL)
{
                         p=head;
                         while(p->pid!=pid1&&p->next!=NULL)
                            p=p->next;
                            if(p->pid==pid1)
                        strcpy(p->state,"stopped");
                            else{
                                 add_node(input,pid1);
                                strcpy(end->state,"stopped");
                               }
                  }
else
{
                                   add_node(input,pid1);
                                   strcpy(end->state,"stopped");
                  }
                           sig_z=1;     
                           kill(pid1,SIGSTOP);   
                           for(p=head;p->pid!=pid1;p=p->next)
                           i++;
                           printf("[%d]\t%s\t%s\n",i,end->state,end->cmd);
                           pid1=0;
        }
    /*定*/
/*****************echo command**************************/
  void command_echo(char *arg){
          int i;
   if(arg!=NULL){
         for(i=0;i<strlen(arg);i++)
           printf("%c",arg);
            printf("\n");
              }

}  
/*********************************************************/
  void print_help(){
                        printf("  help --  show the all command\n");
                            printf("  exit or quit or bye --  exit  \n ");
                            printf("  cd  --      show the path\n");
                            printf("  history --  show the used command\n");
                            printf("  jobs --  show the running's process\n");
                            printf("  echo < >  show the letter \n");
                        printf("  mkdir filename -- create  a new file!\n");
                        printf("  rmdir filename -- delete  the  file!\n");
                        printf("  en or environ -- show  the  PATH!\n");
   
   }  
/***********************************************************/
  void command_mkdir(const char *f){
             if(f!=NULL)
                      if(mkdir(f,660)<0)
                       printf("can't create file!\n");
}
/**************************************************************/
  void command_rmdir(char *fn){
    if(fn!=NULL)
          if(rmdir(fn)<0)
            printf("can't delete the file!\n");
    }
/**********************environ**********************************/
void command_environ(){
     int fd,read_num,i;
       char *buffer;
    fd=open("sh_profile",O_RDONLY,00700);
   if(fd==-1){
        printf("init wrong!");
        exit(1);
         }
     else {
        buffer=(char *)malloc(sizeof(char)*BUFFERSIZE);
     read_num=read(fd,buffer,BUFFERSIZE);
     }
    for(i=0;i<BUFFERSIZE;i++)
   printf("%c",buffer);
    printf("\n");}