繁体   English   中英

像“ls -l”这样的命令不在execl中执行,而在execvp中它可以工作

[英]Commands like “ls -l” not executing in execl, whereas in execvp it works

execl变体中使用下面的代码, ls可以工作,但ls -l不起作用,但在我的execvp方法中lsls-l工作。 我采用execl方法的原因是因为二进制文件的路径可能不同而execvp没有为我提供该功能。 理想情况下,我希望execl也可以在ls -l上工作,但是现在它不适用于ls -l 我试过阅读手册页,但没有帮助。

void child(int argc, char *argv[MAX_ARGS])
{
        execvp(argv[0], argv);
}


void child(char *argv[], char* path)
{
        execl(path, argv, NULL);
}

使用execl() ,您必须逐个列出参数; 它只有在您确切知道要提前执行的内容时才有用:

execl("/bin/ls", "ls", "-l", (char *)0);
execl("/bin/sh", "sh", "-c", "ls -l", (char *)0);
execl("/bin/ls", "pink elephants", "-l", (char *)0);

等等。

如果您不知道需要处理多少个参数,请使用execvp()execv*()系列的其他成员之一。 另请注意,您必须指定命令的路径; execvp()搜索$PATH ,但execl()没有。 另请注意,您可以选择传递为argv[0]的值。

我采用execl()方法的原因是因为二进制文件的路径可能不同而execvp()没有为我提供该功能。

我不确定你的意思。 使用execvp() ,您可以指定:

char *argv[] = { "ls", "-l", 0 };
execvp(argv[0], argv);
execv("/bin/ls", argv);

execvp()将在$PATH上搜索ls并执行匹配的第一个程序。 第二个将执行/bin/ls而不查看$PATH

char *argv[] = { "/bin/ls", "-l", 0 };

execv(argv[0], argv);
execvp(argv[0], argv);

这些都可以起作用; 第二个不会使用基于PATH的搜索,因为可执行文件名( argv[0] )包含斜杠。


令我困惑的是execvp(argv[0], argv); 为什么我们将整个argv作为第二个参数传递? 所以假设argv[0]"ls -l" ,为什么我们必须将整个argv作为第二个参数传递?

假设argv[0]包含"ls -l" ,则表示存在问题。 大多数系统没有文件“ /bin/ls -l ”或“ /usr/bin/ls -l ”(其中空白是名称的一部分),但这就是您要执行的内容。

exec*()函数是执行进程的低级函数。 第一个参数指定要运行的程序(通常是二进制;有时是一个带有shebang行的脚本,例如#!/bin/sh作为第一行)。 execv()execvp()execve()execvpe() ,第二个参数是参数的向量,就像main()函数接收参数向量(或参数向量,因此argv )一样。 这是程序参数的以null结尾的列表。 如果要使用选项-l执行ls命令,则需要在argv指定三个(!)值"ls""-l"和空指针:

char argv[] = { "ls", "-l", 0 };

使用execl*()函数,指定要作为第一个参数运行的程序,然后写出参数向量:

execl("/bin/ls", "ls", "-l", (char *)0);

如果你有10个参数,你必须写出10个参数(加上空指针)。

exec*()函数中,名称包含:

  • l - 列表格式参数
  • v - 矢量格式参数
  • p - 对程序执行PATH查找(如果给定名称不包含斜杠)
  • e - 也采用环境变量向量

这些结合起来给出:

  • execl()
  • execv()
  • execlp()
  • execle()
  • execvp()
  • execve()

偶尔有点令人厌烦的是没有execlpe()execvpe() (但请参阅Linux扩展execvpe(3) )。 对于man 2 exec页面来说,从概要中省略其中的一些也是传统的,但在手册页的正文中提到它们 - 传统/遗产可以追溯到1979年至少第7版UNIX™(并且至少持续到RHEL 5 Linux和Mac OS X 10.7.5; man 2 execl页面提到了execve()但未在概要部分中列出它。 其他exec*()函数都可以在execve()上构建 - 这是集合中的基本函数(因此在Linux手册中列为execve(2) )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM