C 为什么不';和执行副总裁一起工作吗?

C 为什么不';和执行副总裁一起工作吗?,c,linux,exec,C,Linux,Exec,我有一个任务要求我写一个迷你shell,它将得到一个命令来执行,执行它,然后等待更多的命令 当我将命令ls.传递给这个迷你shell时,它将打印当前目录的内容。当我传递给它时,它不会打印任何内容。为什么? 这是我的密码: #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <string.h> #include <unistd.h> #incl

我有一个任务要求我写一个迷你shell,它将得到一个命令来执行,执行它,然后等待更多的命令

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

这是我的密码:

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大CMD尺寸40
字符**解析(字符*)//将分析execv/execvp命令的参数。
int main(int argc,字符**argv)
{
bool-debug=false;
断言(argc=0);
if(pid==0)//子级
{
如果(调试)
printf(“信息:子级启动PID[%d]\n”,getpid());
char**buf=parse(命令);
如果(调试)
{
int i;
对于(i=0;buf[i];i++)
printf(“信息:buf[%d]=%s\n”,i,buf[i]);
}
execvp(buf[0],buf);
返回0;
}
否则//父亲
{
智力状态;
等待(&状态);
如果(调试)
printf(“信息:PID[%d]终止的子级,继续等待命令\n”,PID);
}
}
}
字符**解析(字符*字符串)
{
char**ret=malloc(sizeof(char*));
ret[0]=strtok(字符串“”);
int i=0;
for(;ret[i];ret[i]=strtok(NULL,“\n”))
{
ret=realloc(ret,sizeof(char*)*++i);
}
返回ret;
}
您的parse()命令在最后一个参数中包含一个
\n

因此,使用一个ls,实际上执行的是
ls\n
,这当然不在路径中

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

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

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

并且只使用
作为分隔符。

您的解析函数:O,错误肯定来自这里,执行“字符串到单词制表符”函数以后会更容易。@Gabson我也这么认为,但我找不到错误。试着用多个参数运行命令;您将看到只有第一个被传递到
execvp
@chepnerno。这不会发生。已尝试。使用
debug
ls foo bar
应仅在
buf
strtok
中显示
ls
foo
,根据手册,不包括分隔符。无论如何,我从字符串中删除了'\n',重新编译,没有更改。不是重点。尝试更改printf(“信息:buf[%d]='%s'\n',i,buf[i])并运行
minishell-d
:)对于单个令牌,它包括\n.
str[strlen(str)-n]=…
是一个危险的构造。我们应该确保不要传递比
n
短的“字符串”
str
。是的。我甚至不应该提出另一种选择。