使用Execve(Linux)

发布于 2025-02-05 07:19:19 字数 655 浏览 3 评论 0原文

我对使用SystemCall Execve感到困惑。 第二个参数应该是指向参数的指针,但是它不起作用,但是当我将整个命令(/bin/bash) + arg作为第二个参数时,它确实正确执行。

./ test/bin/bash“ Echo'这是一个测试'| WC -C”

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int main(int argc, char *argv[]) {
    execve(argv[1], &argv[1], NULL); ////works, but I dont understand how since the 2nd param is wrong.
    return 0;
}

int main(int argc, char *argv[]) {
    execve(argv[1], &argv[2], NULL);  ////doenst work, it should since Im sending the correct aguments.
    printf("hi");
    return 0;
}

Im confused of the use of the systemcall execve.
The second parameter should be a pointer to the arguments but it doesnt work, it does however execute correctly when I send the whole command(/bin/bash) + arg as a second parameter.

./test /bin/bash "echo 'this is a test' | wc -c"

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int main(int argc, char *argv[]) {
    execve(argv[1], &argv[1], NULL); ////works, but I dont understand how since the 2nd param is wrong.
    return 0;
}

int main(int argc, char *argv[]) {
    execve(argv[1], &argv[2], NULL);  ////doenst work, it should since Im sending the correct aguments.
    printf("hi");
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦冥 2025-02-12 07:19:19

argv [0]包含正在执行的文件的名称。因此,execve还需要将文件作为第一个元素执行(索引0)。

argv[0] contains the name of the file being executed. Therefore, execve also needs the file being executed as first element (index 0).

冷月断魂刀 2025-02-12 07:19:19

来自 execve(2) man page < /a>:

argv是传递给新程序的字符串的一系列指针
作为命令行的参数。按照惯例,第一个
字符串(即,argv [0])应包含相关的文件名
文件执行
argv必须终止数组
通过null指针。 (因此,在新程序中,argv [argc]将是
null。)

换句话说,您在第二个参数中传递的参数列表 incress 可执行本身的名称(即使在第一个参数中已经指定了该列表) 。这就是可执行文件能够检测其被调用的方式(例如,通过符号链接)并在其“帮助”输出中显示正确的名称。

From the execve(2) man page:

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.)

In other words, the arguments list that you pass in the second parameter includes the name of the executable itself (even though that is already specified in the first parameter). This is how executables are able to detect how they're being invoked (e.g. through a symlink) and show the correct name in their "help" output.

梦途 2025-02-12 07:19:19

在Execve Man中,我们可以看到它的原型是:

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

根据Execve Man( https://man7.org/linux/man-pages/man2/execve.2.html

argv是传递给新程序的字符串的一系列指针
作为命令行的参数。按照惯例,其中的第一个
字符串(即,argv [0])应包含相关的文件名
文件执行
。 ARGV阵列必须终止
null指针。 (因此,在新程序中,argv [argc]将是
null。)

关于这些规则,您的代码应该是:

#include <stdio.h>
#include <unistd.h>

int main ()
{

    char *filepath = "/bin/echo";
    char *argv[] = { filepath, "Hello World", NULL };

    execve (filepath, argv, NULL);
  
  return 0;
}

In execve man we can see that its prototype is:

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

According to execve man (https://man7.org/linux/man-pages/man2/execve.2.html)

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.)

In respect to these rules you're code should be:

#include <stdio.h>
#include <unistd.h>

int main ()
{

    char *filepath = "/bin/echo";
    char *argv[] = { filepath, "Hello World", NULL };

    execve (filepath, argv, NULL);
  
  return 0;
}
っ〆星空下的拥抱 2025-02-12 07:19:19

execve呼叫从呼叫者执行程序。就像C中的任何程序一样,它需要argv [0]设置为执行可执行文件的名称。从命令行执行时,通常会自动完成此操作,但是由于您使用execve,因此必须自己执行。
如果argv_1 [1] =&lt; program_2&gt;的可执行路径,当您从program_1调用program_1的execve(argv_1 [1] [1],&amp; argv_1 [1],null),program_2回收一个argv数组,使得argv_2 [0] = argv_1 [1],argv_2 [1] = argv_1 [2] [2]等等。
请注意,您的第二个主体如何不遵守此规则。

execve call executes a program from the caller. Just as any program in C, it requires argv[0] to be set to the name of the executable being executed. This is generally done automatically when executing from command line, but since you're using execve you have to do it yourself.
If argv_1[1] = <executable path for program_2>, when you call program_2 from program_1 with execve(argv_1[1], &argv_1[1], NULL), program_2 recieves an argv array such that argv_2[0] = argv_1[1], argv_2[1] = argv_1[2], and so on.
Notice how your second main does not follow this rule.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文