首页 > 解决方案 > 通过 C 代码在简单的 shell 上保存历史命令

问题描述

我正在用C语言在linux中编写一个简单的shell。我将命令保存在历史记录中,当输入!!时,程序将执行历史记录中保存的最后一个命令。但它不起作用,问题是:
当我输入命令时:ls,argv是ls,历史是ls,但是我输入!!,argv和history都是!!。有人帮我修复这个错误。非常感谢你 !!

void  main(void)
{
     char  line[1024];             
     char  *argv[64];            
     char  *history[64];

     while (1) {                   
          printf("Shell -> ");    
          gets(line);              
          printf("\n");
          parse(line, argv);
          if (strcmp(argv[0], "exit") == 0) 
               exit(0);
          checkDoubleExclmt(argv, history);
          execute(argv);


     }
}
void copyArr(char** des, char** source)
{
   int i = 0;
   for(i; i < sizeof(source)/4; i++)
   {
        des[i] = source[i];
   }
}
void checkDoubleExclmt(char** argv, char** history)
{
    if(strcmp(argv[0], "!!") == 0)
    {
        if(history[0] == NULL)
        {
           printf("\nNo Command in history\n");
        }
        else
        {
           copyArr(argv, history);
        }
    }
    else
    {   
        copyArr(history, argv);
    }

}
void execute(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid = fork()) < 0) {
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {                
          if (execvp(*argv, argv) < 0) {    
               printf("*** ERROR: exec failed\n");
               exit(1);
          }
     }
     else {                                
          while (wait(&status) != pid)     
               ;
     }
}
void parse(char *line, char **argv)
{
     while (*line != '\0') {     
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';     
          *argv++ = line;         
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;            
     }
     *argv = '\0';                 
}

标签: clinuxshell

解决方案


我看到的主要问题是您正在执行指针复制而不是其内容。

    des[i] = source[i]; // pointer copy

应该

   des[i] = strdup(source[i]); //creates memory and copies the contents. You need to free the memory before overwriting.

如果您要使用strdup您的parse()功能,则需要更改以适应内容副本。


   for(i; i < sizeof(source)/4; i++)

sizeof(source是指针的大小而不是数组的大小,您需要将大小显式传递给函数。


推荐阅读