execve 参数的路径名与参数
pathname vs arguments for execve parameters
我正在尝试实现一个 shell 用户输入命令的简单 shell 程序。我希望用户输入“ls”或“dir”并获得 shell 运行 /bin/ls 或 /bin/dir 。对于 execve 参数,什么是正确的:
char *args[] ={"/bin/", "ls", NULL};
//Fork, pid, etc...then
execve(args[0], args+1, NULL);
或者会有所不同??我看到有些人使用 /bin/ls
作为路径名,然后没有参数,或者 ls
作为路径名,\bin
作为环境?我尝试了上面的方法,但它没有用,所以我想知道这是不是我发送的参数,或者我是否应该在我的代码中的其他地方寻找问题。请注意,我对 execve 的其他变体不感兴趣,例如 execvp。我在 Linux 系统上。谢谢
来自 execve [强调]:
int execve(const char *pathname, char *const argv[],
char *const envp[]);
execve() executes the program referred to by pathname. This
causes the program that is currently being run by the calling
process to be replaced with a new program, with newly initialized
stack, heap, and (initialized and uninitialized) data segments.
pathname must be either a binary executable, or a script starting
with a line of the form:
#!interpreter [optional-arg]
For details of the latter case, see "Interpreter scripts" below.
argv is an array of pointers to strings passed to the new program
as its command-line arguments. By convention, the first of these
strings (i.e., argv[0]) should contain the filename associated
with the file being executed. The argv array must be terminated
by a NULL pointer. (Thus, in the new program, argv[argc] will be
NULL.)
在您的情况下,pathname
应该是 "/bin/ls"
而不是 "/bin/"
。如果你想用命令传递任何命令行参数,你可以为第一个参数提供 argv
向量索引 1
,第二个参数使用索引 2
等等,并终止参数向量NULL
.
用/bin/ls
程序替换当前可执行映像并运行/bin/ls testfile
:
的示例程序
#include <stdio.h>
#include <unistd.h>
int main (void) {
char *args[] = {"/bin/ls", "testfile", NULL};
// here you can call fork and then call execve in child process
execve(args[0], args, NULL);
return 0;
}
输出:
# ./a.out
testfile
路径名
execve()
中的路径名必须是可执行文件的 完整 路径,例如 /bin/ls
。如果使用 execvpe()
,您可以单独使用 ls
作为路径名,但正如您已经指定的那样,您不想使用它。
参数
参数应该是一个字符串数组,每个 space-separated 参数对应一个在命令行上指定的参数。最后一个应该是 NULL。第一个参数应该是路径名本身。例如:
char* args[] = {"/bin/ls", "-la", "foo/bar", NULL};
环境
使用execve()
时不能省略环境变量。在一些实现中,NULL
可以作为最后一个参数传递给execve()
,但这是。相反,您应该传递一个指向空指针的指针;本质上是一个空的环境变量数组。
放在一起
char *args[] ={"/bin/ls", "-foo", "bar", NULL};
//Fork, pid, etc...then
char* nullstr = NULL;
execve(args[0], args, &nullstr);
我正在尝试实现一个 shell 用户输入命令的简单 shell 程序。我希望用户输入“ls”或“dir”并获得 shell 运行 /bin/ls 或 /bin/dir 。对于 execve 参数,什么是正确的:
char *args[] ={"/bin/", "ls", NULL};
//Fork, pid, etc...then
execve(args[0], args+1, NULL);
或者会有所不同??我看到有些人使用 /bin/ls
作为路径名,然后没有参数,或者 ls
作为路径名,\bin
作为环境?我尝试了上面的方法,但它没有用,所以我想知道这是不是我发送的参数,或者我是否应该在我的代码中的其他地方寻找问题。请注意,我对 execve 的其他变体不感兴趣,例如 execvp。我在 Linux 系统上。谢谢
来自 execve [强调]:
int execve(const char *pathname, char *const argv[], char *const envp[]);
execve() executes the program referred to by pathname. This causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.
pathname must be either a binary executable, or a script starting with a line of the form:
#!interpreter [optional-arg]
For details of the latter case, see "Interpreter scripts" below.
argv is an array of pointers to strings passed to the new program as its command-line arguments. By convention, the first of these strings (i.e., argv[0]) should contain the filename associated with the file being executed. The argv array must be terminated by a NULL pointer. (Thus, in the new program, argv[argc] will be NULL.)
在您的情况下,pathname
应该是 "/bin/ls"
而不是 "/bin/"
。如果你想用命令传递任何命令行参数,你可以为第一个参数提供 argv
向量索引 1
,第二个参数使用索引 2
等等,并终止参数向量NULL
.
用/bin/ls
程序替换当前可执行映像并运行/bin/ls testfile
:
#include <stdio.h>
#include <unistd.h>
int main (void) {
char *args[] = {"/bin/ls", "testfile", NULL};
// here you can call fork and then call execve in child process
execve(args[0], args, NULL);
return 0;
}
输出:
# ./a.out
testfile
路径名
execve()
中的路径名必须是可执行文件的 完整 路径,例如 /bin/ls
。如果使用 execvpe()
,您可以单独使用 ls
作为路径名,但正如您已经指定的那样,您不想使用它。
参数
参数应该是一个字符串数组,每个 space-separated 参数对应一个在命令行上指定的参数。最后一个应该是 NULL。第一个参数应该是路径名本身。例如:
char* args[] = {"/bin/ls", "-la", "foo/bar", NULL};
环境
使用execve()
时不能省略环境变量。在一些实现中,NULL
可以作为最后一个参数传递给execve()
,但这是
放在一起
char *args[] ={"/bin/ls", "-foo", "bar", NULL};
//Fork, pid, etc...then
char* nullstr = NULL;
execve(args[0], args, &nullstr);