C execlp()没有正确解析参数字符串

时间:2011-01-20 06:12:47

标签: c shell

我正在为操作系统类构建一个shell,它必须使用exec()或其变体之一来执行外部命令。目前,我正在使用execlp(command,command_parameters, (char *) NULL)。这运行命令很好(例如ls返回标准目录列表),但似乎没有解析任何参数(例如运行mkdir hello抛出错误“hello:缺少操作数...尝试'hello --help'获取更多信息。)我缺少什么?

            else // Try to handle an external command
        {
            char *command_parameters = malloc(sizeof(raw_command)-sizeof(command));
            strcpy(command_parameters, raw_command+strlen(command)+1);
            pmesg(1, "Command is %s.\n", command);
            pmesg(1, "The command parameters are %s.\n", command_parameters);
            pid_t pid = fork();
            pmesg(1, "Process forked. ID = %i. \n", pid);
            int status;
            if (fork < 0)
            {
                printf("Could not fork a process to complete the external command.\n");
                exit(EXIT_FAILURE);
            }
            if (pid == 0) // This is the child process
            {
                pmesg(1, "This is the child process, running execlp.\n");
                if (execlp(command, command_parameters, (char *) NULL) < 0)
                {
                    printf("Could not execute the external command.\n");
                    exit(EXIT_FAILURE);
                }
                else    { pmesg(1, "Executed the child process.\n"); }
            }
            else {while(wait(&status) != pid); } // Wait for the child to finish executing
            pmesg(1, "The child has finished executing.\n");
        }

pmesg是一个调试标记,用于打印给定某个调试级别的语句。)

谢谢!

1 个答案:

答案 0 :(得分:3)

这里有几个问题:

  1. execlp( const char *file, const char *arg, ...)期望将参数拆分并单独传递,而不是作为一个大字符串。
  2. 第一个arg(在const char *file之后)按惯例,是您正在运行的可执行文件的名称,它将被放入被调用程序中的argv[0]。因此,第一个参数需要追求它。
  3. e.g:

    execlp( command, command, arg1, arg2, ..., (char *)NULL );
    

    用你所拥有的,像:

    execlp( command, command, command_parameters, (char *)NULL );
    

    可能会按原样使用"mkdir", "hello"来处理您的问题,但您仍然没有将command_parameters字符串拆分,因此如果没有修改更多的命令,它将无法工作而不是一个论点。

    编辑:P.S。你的行

    if (fork < 0)
    

    应该是

    if (pid < 0)