简体   繁体   English

execve 参数的路径名与 arguments

[英]pathname vs arguments for execve parameters

I am trying to implement a simple shell program that runs user input commands.我正在尝试实现一个运行用户输入命令的简单 shell 程序。 I want the user to enter "ls" or "dir" and have the shell run /bin/ls or /bin/dir.我希望用户输入“ls”或“dir”并让 shell 运行 /bin/ls 或 /bin/dir。 For the execve argument what would be correct:对于 execve 参数,什么是正确的:

char *args[] ={"/bin/", "ls", NULL};
//Fork, pid, etc...then
execve(args[0], args+1, NULL);

Or would it be something different??还是会有所不同?? I've see some people using /bin/ls as the pathname and then no arguments or ls as the pathname and \bin for the environment?我看到有些人使用/bin/ls作为路径名,然后没有 arguments 或ls作为路径名和\bin作为环境? I tried what I had above and it didn't work so I want to know if it is the arguments I am sending it or whether I should be looking elsewhere in my code for the problem.我尝试了上面的方法,但它没有用,所以我想知道它是否是我发送的 arguments,或者我是否应该在我的代码中的其他地方寻找问题。 Note I am not interested in other variations of execve such as execvp.请注意,我对 execve 的其他变体不感兴趣,例如 execvp。 I am on a Linux system.我在 Linux 系统上。 Thanks谢谢

PATHNAME路径名

The pathname in execve() must be the full path to the executable, such as /bin/ls . execve()中的路径名必须是可执行文件的完整路径,例如/bin/ls If using execvpe() , you could use ls alone as the pathname, but as you already specified, you don't want to use that.如果使用execvpe() ,您可以单独使用ls作为路径名,但正如您已经指定的那样,您不想使用它。

ARGUMENTS ARGUMENTS

The arguments should be an array of strings, one for each space-separated argument specified on the command line. arguments 应该是一个字符串数组,一个字符串对应命令行上指定的每个以空格分隔的参数。 The last one should be NULL. The first argument should be the pathname itself.最后一个应该是 NULL。第一个参数应该是路径名本身。 For example:例如:

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

ENVIRONMENT环境

The environment variables cannot be omitted when using execve() .使用execve()时不能省略环境变量。 In some implementations , NULL can be passed as the last argument to execve() , but this is not standard .某些实现中, NULL可以作为最后一个参数传递给execve() ,但这不是标准的。 Instead, you should pass a pointer to a null pointer;相反,您应该传递一个指向 null 指针的指针; essentially an empty array of environment variables.本质上是一个空的环境变量数组。

Putting it together把它放在一起

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

From execve [emphasis added] :来自execve [强调添加]

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

execve() executes the program referred to by pathname. execve() 执行路径名引用的程序。 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 (ie, argv[0]) should contain the filename associated with the file being executed. argv 是一个指针数组,指向作为命令行 arguments 传递给新程序的字符串。按照惯例,这些字符串中的第一个(即 argv[0])应该包含与正在执行的文件关联的文件名。 The argv array must be terminated by a NULL pointer. argv 数组必须以 NULL 指针结尾。 (Thus, in the new program, argv[argc] will be NULL.) (因此,在新程序中,argv[argc] 将为 NULL。)

In your case, the pathname should be "/bin/ls" and not "/bin/" .在您的情况下, pathname应该是"/bin/ls"而不是"/bin/" If you want to pass any command line argument with the command, you can provide first argument them with argv vector index 1 , second argument with index 2 and so on and terminate the argument vector with NULL .如果你想通过命令传递任何命令行参数,你可以为第一个参数提供argv向量索引1 ,第二个参数索引2等等,并用NULL终止参数向量。

A sample program which replace the current executable image with /bin/ls program and runs /bin/ls testfile :一个用/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: Output:

# ./a.out 
testfile

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

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