![](/img/trans.png)
[英]Execvp works with "ls -l | wc" and failed with "ls -l|wc
[英]Commands like “ls -l” not executing in execl, whereas in execvp it works
在execl
变体中使用下面的代码, ls
可以工作,但ls -l
不起作用,但在我的execvp
方法中ls
和ls-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.