2011-05-05 165 views
0

當前正在接收輸入linux shell命令的程序,並執行它們來創建子進程。從用戶輸入獲取shell命令並執行C程序

#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 

int main(int argc, char * argv[]) 
{ 
    int pid, status; 
    if (argc < 2) { 
    printf("Usage: %s command, [arg1 [arg2]...]\n", argv[0]); 
    return EXIT_FAILURE; 
    } 
    printf("Starting %s...\n", argv[1]); 
    pid = fork(); 
    if (pid == 0) { 
    execvp(argv[1], &argv[1]); 
    perror("execvp"); 
    return EXIT_FAILURE; // Never get there normally 
    } else { 
    if (wait(&status) == -1) { 
     perror("wait"); 
     return EXIT_FAILURE; 
    } 
    } 
    return EXIT_SUCCESS; 
} 

作品與像./program command arg輸入,但需要與例如ARGS接收各種命令:./program command arg command arg .....

任何建議?

回答

0

你實際上沒有說出你的問題是什麼,但我的猜測是你在解決每個分支進程如何使用參數時遇到問題。

我想你所做的就是每次fork時你需要將argv指針前進到下一個命令/ arg對。當命令是零終止符時,該分叉循環終止。

我希望我已經理解你的問題,因爲你沒有真正說明你被困在這個問題的哪個方面。

0

argc告訴你的argv

你需要使用這些信息從argv提取它們的大小。

請注意,這並不能解決具有不同參數個數的命令問題。

編輯因爲這個原因在答覆意見:

你可以看一下getopt()這將允許你這樣做:

./program -c "command arg1 arg2" -c "command arg1" ... 

的問題是,你需要能夠區分你的命令/ arg集。 getopt()至少會讓你有一半的路,那麼你只需要解析每一組。雖然這是真正的矯枉過正,因爲這是您唯一的輸入類型。在這種情況下,通過argv迭代就可以輕鬆完成。

另一種辦法是將它們與分隔符分開:

./program command arg1, command arg1 arg2, ... 

你會需要通過argv迭代,並查找逗號知道一個命令/ ARG組完成。或者將所有的argv連接成字符串並使用strtok()。有點醜陋的恕我直言,但可行。

+0

但我想讓用戶使用任意數量的命令與參數,當然,我將不得不改變,如果(argc> 2),但不知道如何處理,而不知道用戶命令的數量想要輸入。 – Devoid 2011-05-05 20:43:16

+1

你要麼需要通過它們作爲單一,引用參數(如:'./program「命令ARG ARG」「命令2 ARG ARG」'),然後分析每個字符串,或拿出一個分隔符,讓你知道當一個命令/ ARG設置完成(通過'argv'迭代) – 2011-05-05 20:57:08

+0

其實......你可能* *能夠與getopt的()來做到這一點,它已經有一段時間...尋找 – 2011-05-05 21:01:36

0

一個shell是一個複雜的軟件,我最近不得不爲一個操作系統類實現一個,這很困難;我們只需要控制每個輸入的一個命令(儘管我們也必須實現I/O重定向和管道,並且必須手動執行路徑搜索,然後使用execv()執行)。

您將面臨的問題在於,實際上沒有辦法確定命令行參數數組中的下一個arg字符串是否是前一個命令的命令或參數。唯一的方式,你可以區分命令及其參數表是,如果你知道,它會交替command arg command arg ...,或有每個命令的參數(這是不是非常有用)其他一些標準化的數量或有這樣一個分號命令之間的deliminator :command arg; command arg arg arg; ...

在這種情況下,你知道將交替那麼你可以通過ARGS像這樣的循環:

for(int i = 1; i < argc; i += 2) 
{ 
    //command is argv[i], arg is argv[i + 1] 
} 

一個更好的辦法來做到這一點,是不是使用命令行參數創建一個輸入提示,然後每行處理一個命令,就像一樣mal shell使用情況。

+0

嗯,我還有其他的方式與處理呢while(1){print(「Shell - >」); gets(line); printf(「\ n」); parse(line,argv); 如果(的strcmp(argv的[0], 「退出」)== 0) 出口(0); execute(argv); }'但是這樣一來就會看起來像一個外殼,但我假裝讓用戶可以在同一行參數執行各種命令。 – Devoid 2011-05-05 20:50:37

0

我覺得這裏的問題是解析argv的。

這是一個虛擬的邏輯流程:

for(i = 1; i < argc; i++) 
    { 
     isCommand = CheckCmd(argv[i]); /* check if argv[i] is a command */ 
     if (isCommand) 
     { 
      for(; i < argc; i++) 
      { 
       isCommand = CheckCmd(argv[i]); /* check if argv[i] is a command */ 
       if (isNotCommand) 
       { 
        PushOption(argv[i]); /* save options */ 
       } else 
       { 
        /* Get Command and options from stack */ 
        /* execute command with fork/execv */ 
       } 
      } 
     } 
    } 

你需要在這裏的唯一的事情就是實現CheckCmd和PushOption/PopOption。