`execve()`在与”which”一起使用时没有输出到终端。

huangapple go评论64阅读模式
英文:

execve() when used with "which" is not outputting to terminal

问题

我正在尝试检索通过命令行参数传递给程序的路径。

例如:

运行 ./a.out results.txt wc 应该给我 /usr/bin/wc,但是什么也没有给我。
运行 ./a.out results.txt sdfasfd 会显示“没有这个文件或目录”。

基本上,我正在尝试复制类似于“which cat”或“which wc”等命令行的功能。我正在运行以下测试:

void runtest(char **argv)
{
    char *args[3];
    args[0] = "/usr/bin/which";
    args[1] = argv[2];
    args[2] = NULL;
    printf("正在执行\n");
    execve(args[0], args, NULL);
    perror("");
}

然而,在终端中,我没有得到任何路径的输出。如果有人能告诉我为什么上面的代码不起作用,并且如何根据上面的测试函数获取通过程序传递的命令/可执行文件的路径,我将不胜感激。请注意,我在我的作业中有严格的限制,只能使用execve,并且如果必须的话,使用access()。获取路径之后,我将在另一个函数中使用它来实际运行传递给程序的文件上的命令,比如./a.out results.txt cat。我不能硬编码路径,因为cat、wc等命令并不总是共享相同的路径。谢谢。

英文:

I am attempting to retrieve the path of a command line argument I pass through to a program.
e.g

running ./a.out results.txt cat should give me /bin/cat but gives me nothing
running ./a.out results.txt wc should give me /usr/bin/wc but gives me nothing
running ./a.out results.txt sdfasfd results in No such file or directory

basically I am trying to reproduce the "which cat" or "which wc" etc command line.
I am running the following test

    void runtest(char **argv)
    {
	  char *args[3];
	  args[0] = "/usr/bin/which";
	  args[1] = argv[2];
	  args[2] = NULL;
	  printf("EXECUTING \n");
	  execve(args[0], args, NULL);
	  perror("");
    }

I am however not getting any output in terminal of path.
I would appreciate if somebody could advise me why the above does not workhow to retrieve the path for the command/executable passed through to the program based on above test function WITHOUT any new additional functions (I have strict restrictions for my assignment and can only use execve and if I must, access().

Once the path is retrieved I will be using it in another function to actually run the command on the file passed through to program as per ./a.out results.txt cat.
I cannot hardcode the path as cat, wc and others dont always share the same Path.
Thank you

答案1

得分: 1

手册页execve(2)

在Linux上,argvenvp可以指定为NULL。在这两种情况下,这与指定参数为指向包含单个空指针的列表的效果相同。不要利用这个非标准且不可移植的错误特性!在许多其他UNIX系统上,将argv指定为NULL会导致错误(EFAULT)。一些其他UNIX系统将envp==NULL的情况视为与Linux相同。

因此,即使您在Linux上,您也正在设置一个不包含PATH变量的空环境,因此搜索失败。在我的系统上,which会打印错误:

/usr/bin/which: no cat in ((null))

如果您使用execv而不是execve,它将正常工作,后者不需要环境,只是继承父进程的环境:

execv(args[0], args);
英文:

The manual page execve(2) says:

> On Linux, argv and envp can be specified as NULL. In both cases, this has the same effect as specifying the argument as a pointer to a list containing a single null pointer. Do not take advantage of this nonstandard and nonportable misfeature! On many other UNIX systems, specifying argv as NULL will result in an error (EFAULT). Some other UNIX systems treat the envp==NULL case the same as Linux.

So, even if you're on Linux, you're setting an empty environment that doesn't contain even a PATH variable, so the search fails. On my system, an error is printed by which:

/usr/bin/which: no cat in ((null))

It works if you use execv instead, which doesn't require an environment and just inherits it from the parent process:

        execv(args[0], args);

huangapple
  • 本文由 发表于 2023年4月17日 15:48:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76032799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定