【问题标题】:unistd's execl() without passing any argumentsunistd 的 execl() 没有传递任何参数
【发布时间】:2015-12-21 16:45:50
【问题描述】:

在我的代码中,我需要执行/bin/bash,但我不想在不传递任何参数的情况下执行它。我是这样写的:

execl("/bin/bash", NULL);

然后,通过一些研究,我意识到我还需要添加类型转换:

execl("bin/bash", (char*) NULL);

但 GCC 仍然给我警告:

main.c:18:5: warning: null argument where non-null required (argument 2) [-Wnonnull]
     if(execl("/bin/bash", (char*) NULL) == -1) {
     ^
main.c:18:5: warning: not enough variable arguments to fit a sentinel [-Wformat=]

这样做的正确方法是什么,是我误解了什么,还是我使用了完全错误的函数调用?

【问题讨论】:

  • 到目前为止,您已经得到了几个基本相同的答案。我会注意到获取登录 shell 的经典方法是 execl("/bin/sh", "-sh", (char *)0),其中- 表示它是登录 shell。 Bash(和其他一些 shell)已经对其进行了规范化,以便 execl("/bin/bash", "bash", "-l", (char *)0) 是一个登录 shell。

标签: c linux unistd.h


【解决方案1】:

您收到警告是因为约定是第一个参数始终与正在运行的程序的路径相同,如下所示:

execl("/bin/bash", "/bin/bash", (char*) NULL);

这基本上是当您在 shell 中运行一个没有参数的程序时发生的情况。

这个参数将进入执行程序的argv[0],它可以用来检查它是如何运行的。

【讨论】:

  • 约定是第一个参数是运行时的完整路径,而不仅仅是文件名。但是,您在示例中做对了。
【解决方案2】:

根据man pageexecl()有如下定义:

   int execl(const char *path, const char *arg, ...
                   /* (char  *) NULL */);

GCC 告诉您 execl() 函数需要一个非 NULL 参数。

【讨论】:

    【解决方案3】:

    刚刚遇到类似的问题。我发现如果我指定了我的 exe 的完整路径(以 / 开头),execlp 和 execv 都没有传递任何参数。而且我无法向标准错误输出任何内容。

    由于我只想用自己的克隆版本替换当前进程,因此我保存并使用父进程的 argv[0] 作为 execlp/v 的 2 个第一个参数,一切都很好。

    【讨论】:

      【解决方案4】:

      execl()的前两个参数应该是完整路径,然后是进程名。

      至少我是这么解释的here:

      【讨论】:

      猜你喜欢
      • 2013-06-13
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 2014-05-17
      • 2012-03-26
      • 2021-11-30
      • 2018-06-02
      相关资源
      最近更新 更多