【问题标题】:why wouldn't ls work with execvp?为什么 ls 不能与 execvp 一起使用?
【发布时间】:2013-11-18 16:15:40
【问题描述】:

我有一个任务要求我编写一个 mini-shell——它会得到一个命令来执行,执行它,然后等待更多的命令。

当我将命令ls . 传递给这个迷你shell 时,它会打印当前目录的比赛。当我传递给它ls 它什么也不打印。为什么?

这是我的代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_CMD_SIZE 40
char** parse(char*);//will parse the arguments for the execv/excevp commands.

int main(int argc, char** argv)
{
    bool debug = false;
    assert(argc <= 2);
    if (argc == 2)
    {
        //check for string -debug
        debug = true; 
    } 
    if (debug)
        printf("INFO: Father started PID[%d]\n", getpid());
    char *command = malloc(MAX_CMD_SIZE);
    while(true)
    {
        printf("minishell> ");
        fgets(command, MAX_CMD_SIZE, stdin);
        if (strcmp(command, "exit\n") == 0)
            return 0;
        pid_t pid = fork();
        assert(pid >= 0); 
        if (pid == 0) //child
        {
            if (debug)
                printf("INFO: Child started PID[%d]\n", getpid());
            char** buf = parse(command);
            if (debug)
            {
                int i;
                for (i = 0; buf[i]; i++)
                    printf("INFO: buf[%d] = %s\n",i,buf[i]);
            }
            execvp(buf[0],buf);
            return 0;
        }
        else //father
        {
            int status;
            wait(&status);
            if (debug)
                printf("INFO: Child with PID[%d]terminated, continue waiting commands\n", pid);
        }
    }
}

char** parse(char *string)
{
    char** ret = malloc(sizeof(char*));
    ret[0] = strtok(string, " ");
    int i = 0;
    for (; ret[i]; ret[i] = strtok(NULL, " \n"))
    {
        ret = realloc(ret, sizeof(char*) * ++i);
    }

    return ret;
}

【问题讨论】:

  • 你的解析函数:O,错误肯定来自这里,做一个“字符串到Word选项卡”功能,以后会更容易。
  • @Gabson 我也这么认为,但我找不到错误。
  • 尝试运行带有多个参数的命令;你会看到只有第一个被传递给execvp
  • @chepner 没有。它不会发生。试过了。
  • 对于debugls foo bar 应该只在buf 中显示lsfoo

标签: c linux exec


【解决方案1】:

您的 parse() 命令在最后一个参数中包含 \n :)

因此,使用单个 ls,您实际上是在执行ls\n,它不在 PATH 中(当然)

问题是在第一次strtok() 调用中,您只传递" " 作为分隔符。使用" \n"(就像在随后的调用中一样),问题就消失了。

您也可以通过咀嚼\n 来修复它:

int l = strlen (string);
if (l > 0 && string [l - 1] == '\n') string [l - 1] = '\0';

并且仅使用" " 作为分隔符。

【讨论】:

  • strtok,根据手册,不包括分隔符。无论如何,我从字符串中删除了 '\n',重新编译,没有变化。
  • 不是重点。尝试更改 printf("INFO: buf[%d] = '%s'\n",i,buf[i]); 并运行 minishell -d :) 对于单个令牌,它包括 \n。
  • str[strlen(str) - n] = ... 是一个危险的结构。应该确保不要传入比 n 更短的“字符串”str
  • 是的。我什至不应该提出替代方案。
猜你喜欢
  • 2018-03-09
  • 2021-06-14
  • 2012-10-09
  • 2020-03-18
  • 2017-11-21
  • 2019-04-11
  • 2012-09-19
  • 2013-12-30
  • 2011-04-20
相关资源
最近更新 更多