英文:
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上,
argv
和envp
可以指定为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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论