c-execvp()函数始终返回-1



在我的代码中,我试图使用函数execvp((来执行我在shell中得到的命令,但当我用(例如("ps";它工作得很好,但当它是(命令(时,它就不起作用了,我已经通过从输入行获得命令后打印它来检查命令是否正常,它是一个很好的字符串,没有问题,但函数一直给我返回错误!!

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 100
int main(void)
{
close(2);
dup(1);
char command[BUFFER_SIZE];
while (1)
{
char *arg[3];
fprintf(stdout, "my-shell> ");
memset(command, 0, BUFFER_SIZE);
fgets(command, BUFFER_SIZE, stdin);
if(strncmp(command, "exit", 4) == 0)
{
break;
}
arg[0] = command;
arg[1] = "";
arg[2] = "";
i = execvp(command,arg);
printf("%d",i);
}
return 0;
}

我预计问题出在函数中传递命令的方式上,但在尝试了这么多对代码的编辑之后,我仍然无法弄清楚真正的问题是什么!

有3个主要问题和1个次要问题可以从显示的代码中挑选出来(加上我认为将完整代码简化为问题中的代码的假象,再加上一些奇怪之处(:

  1. fgets()函数在返回的字符串中包括换行符,除非换行符太长(另一个问题(。你需要删除换行符:

    command[strcspn(command, "n")] = '';
    
  2. 代码不解析输入的行,因此只能合理地输入单个单词的命令。要解决这个问题,你必须准备好使用适当的算法将行拆分为单词,在适当的地方删除引号,扩展变量等等。这将是开发shell的后期阶段的一部分。

  3. execvp()的第二个参数需要是以NULL结尾的字符串列表。您只提供命令名和两个没有null终止符的空字符串,这会产生未定义的行为。

小问题是使用""而不是仅使用""是毫无意义的。

问题是代码中没有fork(),因此如果命令成功执行,"shell"将被命令替换,并在替换退出时退出。

close(2); dup(1);序列很奇怪——这意味着标准错误指的是与标准输出相同的文件描述符。那些台词真的不需要(或不可取(。将错误与标准输出分开。

memset()也是多余的。使用fprintf(stdout, "my-shell> ");是编写printf("my-shell> ");的一种有趣方式。使用strncmp(command, "exit", 4)意味着,如果用户键入exit-or-continue,则会将其视为与exit相同,这远非理想。

将这些众多更改中的大部分付诸实施(省略了将命令行解析为单独的参数(留下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#define BUFFER_SIZE 100
int main(void)
{
char command[BUFFER_SIZE];
while (1)
{
printf("my-shell> ");
fflush(stdout);
if (fgets(command, BUFFER_SIZE, stdin) != command)
break;
command[strcspn(command, "n")] = '';
if(strcmp(command, "exit") == 0)
{
break;
}
int pid = fork();
if (pid < 0)
{
fprintf(stderr, "failed to fork()n");
exit(EXIT_FAILURE);
}
if (pid == 0)
{
/* Child - execute command */
/* Should break line into command plus arguments */
char *arg[2];
arg[0] = command;
arg[1] = NULL;
execvp(command, arg);
fprintf(stderr, "failed to execute command '%s'n", command);
exit(EXIT_FAILURE);
}
/* Parent - wait for child to finish */
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
{
if (corpse == pid)
break;
printf("PID %d exited with status 0x%.4Xn", corpse, status);
}
}
return 0;
}

相关内容

  • 没有找到相关文章

最新更新