2014-07-09 7 views
0

我在製作一個支持用戶參數和io重定向的shell程序。我有IO重定向麻煩,如:爲shell程序標記一個char *

$cat <hello> world 

首先我保存的參數在char*陣列。我檢查第一個字符是<還是>,如果是我需要刪除第一個字符並創建一個文件描述符。

這是我正在做的。

char* args[50];//<-- cat <hello and >world are in here 
    char* fd[2]; 
    int fdin, fdout; 
    if(args[j][0] == '<'){ 
     close(fdout); 
     strncpy(fd[0], args[j][1]. strlen(args[j])-1); 
     fdin = open(fd[0], O_RDONLY); 
    } 

回答

0

我假設你從來沒有與main()argcargv參數的經驗?你不需要創建自己的數組,C已經爲你做了。你結束了這個argv數組:

argv[0] = "cat" 
argv[1] = "<" 
argv[2] = "hello" 
argv[3] = ">" 
argv[4] = "world" 

或者:

argv[0] = "cat" 
argv[1] = "<hello" 
argv[2] = ">world" 

或任何組合,這取決於在命令行參數所用的空白。

然後,你可以做這樣的事情(錯誤處理的簡潔省略):

int main(int argc, char** argv) 
{ 
    char* fd[2]; 
    int fdin = -1, fdout = -1; 

    fd[0] = fd[1] = NULL; 

    for (int i = 1; i < argc; ++i) 
    { 
     if (argv[i][0] == '<') 
     { 
      if (argv[i][1] != '\0') 
       fd[0] = &(argv[i][1]); 
      else 
       fd[0] = argv[i+1]; 

      fdin = open(fd[0], O_RDONLY); 
     } 

     else if (argv[i][0] == '>') 
     { 
      if (argv[i][1] != '\0') 
       fd[1] = &(argv[i][1]); 
      else 
       fd[1] = argv[i+1]; 

      fdout = open(fd[1], O_WRONLY); 
     } 
    } 

    ... 

    if (fdin != -1) 
     ... read from fdin as needed ... 
    else 
     ... read from stdin as needed ... 

    ... 

    if (fdout != -1) 
     ... write to fdout as needed ... 
    else 
     ... write to stdout as needed ... 

    ... 

    if (fdin != -1) 
     close(fdin); 

    if (fdout != -1) 
     close(fdout); 

    return 0; 
} 
+1

我認爲這不回答OP問題。他想自己實現shell(而不是執行所有分析工作的shell)。所以他有一些東西要讀取輸入(到字符緩衝區)並解析這一行。 – rslemos

+1

注意:'argv [argc] == NULL'。 §5.1.2.2.12 – chux

+0

我的確知道如何使用argc和argv,但這是一個shell程序,就像我首先用./a執行它一樣。出來,然後我提示一些命令,例如。 ls -l。但是,我已經找到了解決此問題的更好方法,感謝您的幫助:D – user3708934

1

爲了方便您的工作,開始起草您輸入的樣子在一些正規的語言,例如:

line : ID+ ('<' ID | '>' '>'? ID)* ('|' line)* '\0' 

其中ID是運行,其中每個或者​​或isDigitisSpecial通過其它字符分離(如空格字符,製表符,「>」的,「<」,「|」等

012。

在解析過程中,將第一部分(ID+)添加到鏈接列表中,然後將該列表轉換爲argv-argc對會更容易。

其餘的都是經過特殊處理的(未鏈接列表,因爲它們並不像一般):

  • IO重定向與「<」和「>」和「>>」;然後
  • 使用'|'進行流水線操作。

由於語言是遞歸(注意('|' line)*)解析器容易使其本身也是一個遞歸函數(見你有一個函數parse當它到達?「|」它自稱解析休息)。

注:雖然我表達了類似BNF符號的行語法並不意味着你應該使用語言解析lib或編譯器(想到yacc)。這種語言太簡單,易於實現,值得所有這些工具帶來的麻煩。

相關問題