我不明白 execlp() 在 Linux 中是如何工作的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21558937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
I do not understand how execlp() works in Linux
提问by Arman Iqbal
I have spent the last 2 days trying to understand the execlp()
system call, but yet here I am. Let me get straight to the issue.
过去 2 天我一直在试图理解execlp()
系统调用,但我还是在这里。让我直截了当地说明问题。
The man page
of execlp declares the system call as int execlp(const char *file, const char *arg, ...);
with the description: The const char arg and subsequent ellipses in the execl(), execlp(), and execle() functions can be thought of as arg0, arg1, ..., argn.
在man page
execlp的声明系统调用为int execlp(const char *file, const char *arg, ...);
与描述:该为const char ARG和随后的椭圆在execl的(),execlp()和execle()函数可以作为为arg0,ARG1,...,ARGN被认为。
Yet I see the system call being called like this in our text book: execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);
(the "..." are for us to figure out as students). However this system call doesn′t even resemble anything like the declaration on the man page
of the system call.
然而,我在我们的教科书中看到系统调用是这样调用的:(execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...);
“...”是我们作为学生来理解的)。然而,这个系统调用甚至不像系统调用的声明那样man page
。
I am super confused. Any help is appreciated.
我超级困惑。任何帮助表示赞赏。
采纳答案by nos
this prototype:
这个原型:
int execlp(const char *file, const char *arg, ...);
Says that execlp ìs a variable argument function. It takes 2 const char *
. The rest of the arguments, if any, are the additional arguments to hand over to program we want to run - also char *
- all these are C strings (and the last argument must be a NULL pointer)
说 execlp 是一个可变参数函数。它需要 2 const char *
。其余的参数,如果有的话,是要交给我们要运行的程序的附加参数——同样char *
——所有这些都是 C 字符串(最后一个参数必须是一个 NULL 指针)
So, the file
argument is the path name of an executable file to be executed. arg
is the string we want to appear as argv[0]
in the executable. By convention, argv[0]
is just the file name of the executable, normally it's set to the same as file
.
因此,file
参数是要执行的可执行文件的路径名。arg
是我们想要argv[0]
在可执行文件中出现的字符串。按照惯例,argv[0]
只是可执行文件的文件名,通常它设置为与file
.
The ...
are now the additional arguments to give to the executable.
在...
现在的其他参数给予可执行文件。
Say you run this from a commandline/shell:
假设你从命令行/shell 运行它:
$ ls
That'd be execlp("ls", "ls", (char *)NULL);
Or if you run
这会是execlp("ls", "ls", (char *)NULL);
或者,如果你运行
$ ls -l /
That'd be execlp("ls", "ls", "-l", "/", (char *)NULL);
那会是 execlp("ls", "ls", "-l", "/", (char *)NULL);
So on to execlp("/bin/sh", ..., "ls -l /bin/??", ...);
所以继续 execlp("/bin/sh", ..., "ls -l /bin/??", ...);
Here you are going to the shell, /bin/sh , and you're giving the shell a command to execute. That command is "ls -l /bin/??". You can run that manually from a commandline/shell:
在这里,您将进入外壳程序 /bin/sh ,并向外壳程序提供要执行的命令。该命令是“ls -l /bin/??”。您可以从命令行/shell 手动运行它:
$ ls -l /bin/??
Now, how do you run a shell and tell it to execute a command ? You open up the documentation/man page for your shell and read it.
现在,您如何运行 shell 并告诉它执行命令?您打开 shell 的文档/手册页并阅读它。
What you want to run is:
你想要运行的是:
$ /bin/sh -c "ls -l /bin/??"
This becomes
这变成
execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);
Side note:
The /bin/??
is doing pattern matching, this pattern matching is done by the shell, and it expands to all files under /bin/ with 2 characters. If you simply did
旁注:/bin/??
正在做模式匹配,这个模式匹配是由shell完成的,它扩展到/bin/下的所有文件,有2个字符。如果你只是做了
execlp("ls","ls", "-l", "/bin/??", (char *)NULL);
Probably nothing would happen (unless there's a file actually named /bin/??
) as there's no shell that interprets and expands /bin/??
可能什么都不会发生(除非有一个实际命名/bin/??
为的文件),因为没有解释和扩展 /bin/??
回答by lihudi
The limitation of execl is that when executing a shell command or any other script that is not in the current working directory, then we have to pass the full path of the command or the script. Example:
execl 的局限性在于,当执行 shell 命令或任何其他不在当前工作目录中的脚本时,我们必须传递命令或脚本的完整路径。例子:
execl("/bin/ls", "ls", "-la", NULL);
The workaround to passing the full path of the executable is to use the function execlp, that searches for the file (1st argument of execlp) in those directories pointed by PATH:
传递可执行文件的完整路径的解决方法是使用函数execlp,该函数在 PATH 指向的那些目录中搜索文件(execlp 的第一个参数):
execlp("ls", "ls", "-la", NULL);