【问题标题】:I do not understand how execlp() works in Linux我不明白 execlp() 在 Linux 中的工作原理
【发布时间】:2014-02-28 19:16:27
【问题描述】:

过去 2 天我一直在试图理解 execlp() 系统调用,但我在这里。让我直奔主题。

execlp 的man page 将系统调用声明为int execlp(const char *file, const char *arg, ...);,其描述如下: 可以认为 execl()、execlp() 和 execle() 函数中的 const char arg 和后续省略号作为 arg0, arg1, ..., argn。

然而,我在我们的教科书中看到系统调用是这样调用的:execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);(“...”是我们作为学生来理解的)。然而,这个系统调用甚至不像系统调用的man page 上的声明。

我很困惑。任何帮助表示赞赏。

【问题讨论】:

  • 因为在手册页中它是函数的定义,我猜在你的教科书中它是如何使用它的一个例子
  • 你是对的。但是在上面的例子中它到底想做什么以及它是如何被使用的呢? Google 在 execlp() 上的信息非常糟糕。
  • 你是什么意思它“甚至不像”声明?参数是char *。这非常类似于 char *!

标签: c linux exec


【解决方案1】:

这个原型:

  int execlp(const char *file, const char *arg, ...);

说 execlp 是一个可变参数函数。它需要 2 个const char *。其余参数(如果有的话)是要交给我们要运行的程序的附加参数 - 也是 char * - 所有这些都是 C 字符串(最后一个参数必须是 NULL 指针)

因此,file 参数是要执行的可执行文件的路径名。 arg 是我们希望在可执行文件中显示为 argv[0] 的字符串。按照惯例,argv[0] 只是可执行文件的文件名,通常设置为与file 相同。

... 现在是提供给可执行文件的附加参数。

假设您从命令行/shell 运行它:

$ ls

那就是execlp("ls", "ls", (char *)NULL); 或者如果你运行

$ ls -l /

那就是execlp("ls", "ls", "-l", "/", (char *)NULL);

继续execlp("/bin/sh", ..., "ls -l /bin/??", ...);

在这里,您将进入 shell, /bin/sh ,并且您正在给 shell 一个要执行的命令。该命令是“ls -l /bin/??”。您可以从命令行/shell 手动运行它:

 $ ls -l /bin/??

现在,如何运行 shell 并告诉它执行命令?您打开 shell 的文档/手册页并阅读它。

你要运行的是:

$ /bin/sh -c "ls -l /bin/??"

这就变成了

  execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);

旁注: /bin/?? 正在做模式匹配,这个模式匹配是由 shell 完成的,它扩展到 /bin/ 下的所有文件,包含 2 个字符。如果你只是这样做了

  execlp("ls","ls", "-l", "/bin/??", (char *)NULL);

可能什么都不会发生(除非有一个实际上名为 /bin/?? 的文件),因为没有解释和扩展 /bin/?? 的 shell

【讨论】:

  • 是否有任何特殊的头文件需要运行这样的 shell 命令?我尝试了上面的例子,我收到了一堆错误,比如error: stray ‘\235’ in programerror: too few arguments to function ‘execlp’。我猜它是因为缺少头文件。我使用了这样的函数:execlp(“/bin/sh”,“/bin/sh”, "-c", mystring, (char *)NULL); 其中 mystring 是一个字符串变量,其中包含我希望 execlp() 执行的任何 bash 命令的输入字符串。
  • @ArmanIqbal 引号不知何故在这里改变了。但这是 C 代码,因此将字符串更改为用双引号引起来。这些:" 另请阅读 execlp 的手册页,了解您需要包含哪些头文件
【解决方案2】:

execl 的限制是当执行一个shell命令或任何其他不在当前工作目录中的脚本时,我们必须传递命令或脚本的完整路径。 示例:

execl("/bin/ls", "ls", "-la", NULL);

传递可执行文件的完整路径的解决方法是使用函数 execlp,该函数在指向的目录中搜索文件(execlp 的第一个参数)路径:

execlp("ls", "ls", "-la", NULL);

【讨论】:

  • 如果我使用 execl("/bin", "ls", "-la", NULL);只提到目录名而不是文件的完整路径。
  • @pankajkushwaha:不,第一个参数必须指向你要执行的可执行文件
  • 你不一定要传递完整路径;例如你可以通过../bin/some_command.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 2021-01-06
  • 2021-06-09
相关资源
最近更新 更多