2011-05-05 159 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。