为什么执行ls时没有输出?
Why is no output produced when executing ls?
我正在尝试编写一个程序来执行 argv 中给出的任何内容。但是,当我实际上 运行 execvp 时,它没有给出任何输出,也没有产生任何错误。这是我的程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char * argv[]) {
char * args[argc];
for (int i = 0; i < argc - 1; ++i)
args[i] = strdup(argv[i+1]);
args[argc-1] = malloc(1);
*args[argc-1] = '[=10=]';
printf("%s\n", args[argc-1]);
int rc = fork();
if (rc == 0)
execvp(args[0], args);
}
当我 运行 ./exec ls 时产生的输出只是一个空行。但是,如果我 运行 一个将 ls 硬编码到数组中的程序,它就可以正常工作。为什么这个程序没有列出目录的内容?
假装有必要复制参数并使用 fork()
,并观察如果您 运行:
./exec ls
那么您只想在对 execvp()
的调用中使用索引 1 中的参数,然后您将得到如下代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
char *args[argc];
for (int i = 0; i < argc - 1; ++i)
{
if ((args[i] = strdup(argv[i+1])) == NULL)
{
fprintf(stderr, "%s: failed to allocate memory for '%s'\n",
argv[0], argv[i+1]);
exit(EXIT_FAILURE);
}
}
args[argc-1] = NULL;
int rc = fork();
if (rc == 0)
{
execvp(args[0], args);
fprintf(stderr, "%s: failed to execute '%s'\n", argv[0], args[0]);
exit(EXIT_FAILURE);
}
else if (rc < 0)
{
fprintf(stderr, "%s: failed to fork\n", argv[0]);
exit(EXIT_FAILURE);
}
return 0;
}
父进程在退出之前确实应该为子进程 wait()
。该代码可能应该包含一个函数来转储参数列表的内容。这是代码的修订版本,它不使用 strdup()
尽管它仍然是分叉的。它使用了我的 SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c
and stderr.h
in the src/libsoq 子目录中可用的一些代码。这些简化了错误处理——错误报告使用单个函数调用而不是像以前那样使用多行代码。
#include <unistd.h>
#include <sys/wait.h>
#include "stderr.h"
int main (int argc, char *argv[])
{
err_setarg0(argv[0]);
if (argc <= 1)
err_usage("cmd [arg ...]");
int rc = fork();
if (rc == 0)
{
execvp(argv[1], &argv[1]);
err_syserr("failed to execute '%s': ", argv[1]);
}
else if (rc < 0)
err_syserr("failed to fork: ");
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
{
if (corpse != rc)
err_remark("unexpected child PID %d status 0x%.4X\n", corpse, status);
}
if (WIFEXITED(status))
rc = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
rc = 128 + WTERMSIG(status);
else
rc = 255; /* Something weird happened! */
return rc;
}
当然,如果你不使用fork()
,你也不需要wait()
。这从根本上减少了代码:
#include <unistd.h>
#include "stderr.h"
int main (int argc, char *argv[])
{
err_setarg0(argv[0]);
if (argc <= 1)
err_usage("cmd [arg ...]");
execvp(argv[1], &argv[1]);
err_syserr("failed to execute '%s': ", argv[1]);
}
我正在尝试编写一个程序来执行 argv 中给出的任何内容。但是,当我实际上 运行 execvp 时,它没有给出任何输出,也没有产生任何错误。这是我的程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char * argv[]) {
char * args[argc];
for (int i = 0; i < argc - 1; ++i)
args[i] = strdup(argv[i+1]);
args[argc-1] = malloc(1);
*args[argc-1] = '[=10=]';
printf("%s\n", args[argc-1]);
int rc = fork();
if (rc == 0)
execvp(args[0], args);
}
当我 运行 ./exec ls 时产生的输出只是一个空行。但是,如果我 运行 一个将 ls 硬编码到数组中的程序,它就可以正常工作。为什么这个程序没有列出目录的内容?
假装有必要复制参数并使用 fork()
,并观察如果您 运行:
./exec ls
那么您只想在对 execvp()
的调用中使用索引 1 中的参数,然后您将得到如下代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
char *args[argc];
for (int i = 0; i < argc - 1; ++i)
{
if ((args[i] = strdup(argv[i+1])) == NULL)
{
fprintf(stderr, "%s: failed to allocate memory for '%s'\n",
argv[0], argv[i+1]);
exit(EXIT_FAILURE);
}
}
args[argc-1] = NULL;
int rc = fork();
if (rc == 0)
{
execvp(args[0], args);
fprintf(stderr, "%s: failed to execute '%s'\n", argv[0], args[0]);
exit(EXIT_FAILURE);
}
else if (rc < 0)
{
fprintf(stderr, "%s: failed to fork\n", argv[0]);
exit(EXIT_FAILURE);
}
return 0;
}
父进程在退出之前确实应该为子进程 wait()
。该代码可能应该包含一个函数来转储参数列表的内容。这是代码的修订版本,它不使用 strdup()
尽管它仍然是分叉的。它使用了我的 SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c
and stderr.h
in the src/libsoq 子目录中可用的一些代码。这些简化了错误处理——错误报告使用单个函数调用而不是像以前那样使用多行代码。
#include <unistd.h>
#include <sys/wait.h>
#include "stderr.h"
int main (int argc, char *argv[])
{
err_setarg0(argv[0]);
if (argc <= 1)
err_usage("cmd [arg ...]");
int rc = fork();
if (rc == 0)
{
execvp(argv[1], &argv[1]);
err_syserr("failed to execute '%s': ", argv[1]);
}
else if (rc < 0)
err_syserr("failed to fork: ");
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
{
if (corpse != rc)
err_remark("unexpected child PID %d status 0x%.4X\n", corpse, status);
}
if (WIFEXITED(status))
rc = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
rc = 128 + WTERMSIG(status);
else
rc = 255; /* Something weird happened! */
return rc;
}
当然,如果你不使用fork()
,你也不需要wait()
。这从根本上减少了代码:
#include <unistd.h>
#include "stderr.h"
int main (int argc, char *argv[])
{
err_setarg0(argv[0]);
if (argc <= 1)
err_usage("cmd [arg ...]");
execvp(argv[1], &argv[1]);
err_syserr("failed to execute '%s': ", argv[1]);
}