2014-12-31 96 views
1

如何在unix shell中添加历史记录功能以允许用户访问最近输入的 命令,用户将能够通过使用 功能访问最多10条命令。UNIX Shell和历史记录功能

这一评论从项目解释历史的一部分:

用户将能够通过使用 功能来访问多达10个命令。命令将从1开始连续编号, 编号将继续超过10.例如,如果用户输入了命令,则最近的10个命令将编号为26到35. 用户将能够列出通过在osh>提示符下输入命令 历史记录 来执行命令历史记录。例如,假设历史由 命令组成(从最多到最近): ps,ls -l,top,cal,who,date 命令历史将输出: 6 ps 5 ls -l 4顶 3卡 2谁 1日 你的程序应该支持两种技术,用于从命令历史命令 : 1.当用户进入!!,最近的历史命令是 执行。 2.当用户输入单个!后跟一个整数N,执行历史记录中的第N个 命令。

这是我的代码,包括历史部分,但我有错误,不知道如何解决它。请帮助

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define MAX_LINE 80 

char *history[10][MAX_LINE]; 
int po; 




void setup(char inputBuffer[], char *args[],int *background) 
{ 
    int length, 
     i,  
     start, 
     ct;  

    ct = 0; 

    length = read(STDIN_FILENO, inputBuffer, MAX_LINE); 

    start = -1; 
    if (length == 0) 
    exit(0);    
    if (length < 0){ 
    perror("error "); 
    exit(-1);   
    } 


    for (i = 0; i < length; i++) { 
    switch (inputBuffer[i]){ 
    case ' ': 
    case '\t' :    
     if(start != -1){ 
      args[ct] = &inputBuffer[start]; 
      ct++; 
     } 
     inputBuffer[i] = '\0'; 
     start = -1; 
     break; 

    case '\n':     
     if (start != -1){ 
      args[ct] = &inputBuffer[start];  
      ct++; 
      } 
     inputBuffer[i] = '\0'; 
     args[ct] = NULL; 
     break; 

    case '&': 
     *background = 1; 
     inputBuffer[i] = '\0'; 
     break; 

    default :    
     if (start == -1) 
      start = i; 
     } 
    }  
args[ct] = NULL; 
} 



int main(void) 
{ 
    char inputBuffer[MAX_LINE]; 
    int background;    
    char *args[MAX_LINE/2+1]; 

while (1){    
    background = 0; 
    printf("os>"); 
     fflush(0); 
     setup(inputBuffer, args, &background);  

    /** 
* After reading user input, the steps are: 
* (1) fork a child process using fork() 
* (2) the child process will invoke execvp() 
* (3) if command included &, parent will invoke wait() 
*/ 

    pid_t pid = fork(); 
    printf("Fork created.\n"); 
/* 
For example, if the 
user enters the command ps -ael at the osh> prompt, the values stored in the 
args array are: 
args[0] = "ps" 
args[1] = "-ael" 
args[2] = NULL 
This args array will be passed to the execvp() function, which has the 
following prototype: 
execvp(char *command, char *params[]); 
*/ 

    if(pid < 0){ 
     printf("Fork failed.\n"); 
    }else if(pid == 0){ 
     if(strcmp(args[0],"history") == 0){ /* Print History */ 
      displayHistory(); 
     }else if(strcmp(args[0],"r") == 0){ /* r num */ 
      int index = (int) args[1]; 
      /*runHistoryAt(index - 1);*/ 
     }else if(strcmp(args[0],"rr") == 0){ /* Run recent */ 
      /*runHistoryAt(0);*/ 
     }else{ /* Execute normally */ 
      printf("executing..., adding to history buffer\n"); 
      /* Add args to history buffer */ 
      int j; 
      for (j = 0; j < sizeof(args); j++) { 
       history[po][j] = args[j]; 
      } 
      po = (po + 1) % 10; 
      /* Execute! */ 
      execvp(args[0],args); 
     } 
    } 

     if(background == 0){ 
      wait(NULL); 
      }else{ 
       setup(inputBuffer, args, &background); 
      } 
     } 
    } 
+1

“我有错误,不知道如何解决它” - 错误是什么? – alfasin

+1

一如既往:用所有警告和调试信息编译('gcc -Wall -Wextra -g')。然后**使用调试器**('gdb') –

+0

@alfasin感谢您的回复,,,错误是这样的一个梨:'os @ debian:〜/ Desktop/gh $ gcc sc -o s.out /tmp/cc5jEhHg.o:在主函数': sc :(。text + 0x1e7):未定义的参考displayHistory' collect2:ld返回1退出状态' – Manar

回答

1

我会使用GNU readline库。它给你线条版本和history支持,你也可以完成。