C++ Can';t以正确的方式执行其他程序

C++ Can';t以正确的方式执行其他程序,c++,execvp,C++,Execvp,我试图从自己的内部执行另一个程序,但我不了解一些事情。所以我写了这段代码: void run() { cout << "##Run" << endl; pid_t process_id = fork(); if (process_id == 0) { char* args[] = { "sudo", "ls", "-l" }; auto i = execvp("sudo", args); cout << "#Result

我试图从自己的内部执行另一个程序,但我不了解一些事情。所以我写了这段代码:

void run() {
  cout << "##Run" << endl;
  pid_t process_id = fork();

  if (process_id == 0) {
    char* args[] = {  "sudo", "ls", "-l" };
    auto i = execvp("sudo", args);
    cout << "#Result: " << i << endl;
    return;
  } else if (process_id < 0) {
    throw std::runtime_error("fork() failed");
  } else if (process_id > 0) {
    wait(&process_id);
  }
  return;
}

void run_decorator() {
  cout << "###Run decorator: " << endl;
  run();
}

int main() {
  run();
  run_decorator();
  return 0;
}
有人能给我解释一下为什么从run\u decorator()函数调用execvp失败吗?

请仔细阅读的文档。它是关于
execl
etc.:

按照惯例,第一个论点应该指向 与正在执行的文件关联的文件名。名单 参数必须由空指针终止,并且,因为它们是 变量函数,此指针必须强制转换为
(char*)NULL

关于
execvp

指针数组必须以空指针终止。

因此,您应该编写以下代码:

char* args[] = {  "sudo", "ls", "-l",  NULL };
execvp("sudo", args);
顺便说一句,
execvp
除了失败之外,根本不返回。不需要在调用后保留其结果

但是,当
execvp
返回时(这只发生在失败时),您需要显示一些错误消息。我建议:

perror("execvp");
exit(EXIT_FAILURE);
在这种情况下,您可以找到有效的参数来调用,而不是。我仍然更喜欢退出(因为它会刷新stdio缓冲区并运行已注册的处理程序)

有人能给我解释一下为什么执行失败吗

对。这是由

不要忘记仔细阅读每一个使用过的函数的文档。对于系统调用(在中列出)和标准C库函数(请参阅),通常应处理故障情况(通常使用
errno
,至少通过
perror
然后
exit

我不明白你为什么需要
sudo
ls
。在很少的情况下,这可能是有用的,因为大多数时候你的程序是可列表的(那么
sudo
是无用的),在这种情况下,你甚至可以使用,with(因此不需要
fork
then
execvp
the
/bin/ls
程序)

还可以阅读和(和)中的技术。请参阅(您可以使用自己的setuid程序避免
sudo


顺便说一句,您应该编译所有警告和调试信息(
g++-Wall-Wextra-g
with)和(可能还有和)。

次要注意:您引用的文档部分错误。有关将
NULL
强制转换为
char*
的部分仅适用于
execl*
系列(它们是varargs,因此不会对变量参数施加特定类型,如果
NULL
只是
0
,因此是
int
-宽度,而不是指针宽度,或者如果指针类型出于任何原因不是恒定宽度,则会导致问题)。它不适用于
execv*
系列(在涉及类型化数组的情况下,
NULL
将被无缝地隐式强制为
char*
)。按照习惯用法,您需要:
char*args[]={“sudo”,“ls”,“-l”,NULL};
,无需强制转换。感谢您的回复,可能明天我会再次仔细研究文档(这次会更仔细).回答你的问题,我不需要将sudo与ls一起使用,这只是一个例子。可能是你不想要的情况
sudo
perror("execvp");
exit(EXIT_FAILURE);