繁体   English   中英

execve 参数的路径名与 arguments

[英]pathname vs arguments for execve parameters

我正在尝试实现一个运行用户输入命令的简单 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作为路径名,然后没有 arguments 或ls作为路径名和\bin作为环境? 我尝试了上面的方法,但它没有用,所以我想知道它是否是我发送的 arguments,或者我是否应该在我的代码中的其他地方寻找问题。 请注意,我对 execve 的其他变体不感兴趣,例如 execvp。 我在 Linux 系统上。 谢谢

路径名

execve()中的路径名必须是可执行文件的完整路径,例如/bin/ls 如果使用execvpe() ,您可以单独使用ls作为路径名,但正如您已经指定的那样,您不想使用它。

ARGUMENTS

arguments 应该是一个字符串数组,一个字符串对应命令行上指定的每个以空格分隔的参数。 最后一个应该是 NULL。第一个参数应该是路径名本身。 例如:

char* args[] = {"/bin/ls", "-la", "foo/bar", NULL};

环境

使用execve()时不能省略环境变量。 某些实现中, NULL可以作为最后一个参数传递给execve() ,但这不是标准的。 相反,您应该传递一个指向 null 指针的指针; 本质上是一个空的环境变量数组。

把它放在一起

char *args[] ={"/bin/ls", "-foo", "bar", NULL};
//Fork, pid, etc...then
char* nullstr = NULL;
execve(args[0], args, &nullstr);

来自execve [强调添加]

 int execve(const char *pathname, char *const argv[], char *const envp[]);

execve() 执行路径名引用的程序。 这导致调用进程当前正在运行的程序被新程序替换,具有新初始化的堆栈、堆和(已初始化和未初始化的)数据段。

路径名必须是二进制可执行文件或以以下形式的行开头的脚本:

   #!interpreter [optional-arg]

有关后一种情况的详细信息,请参阅下面的“解释器脚本”。

argv 是一个指针数组,指向作为命令行 arguments 传递给新程序的字符串。按照惯例,这些字符串中的第一个(即 argv[0])应该包含与正在执行的文件关联的文件名。 argv 数组必须以 NULL 指针结尾。 (因此,在新程序中,argv[argc] 将为 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;
}

Output:

# ./a.out 
testfile

暂无
暂无

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

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