“sh -c”的问题不接受额外参数,UNIX,使用 execve()

发布于 2024-12-19 07:45:42 字数 1459 浏览 1 评论 0原文

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

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

发布评论

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

评论(2

归属感 2024-12-26 07:45:42

您不应在 execve() 的参数内添加引号。应该这样调用:

char *args = { "sh", "-c", "ls -ltga", 0};
execve("/bin/sh", args);

execve() 的第一个参数必须是可执行文件的路径(通常是完整路径)。

You shouldn't put quotes inside arguments of execve(). It should be called like this:

char *args = { "sh", "-c", "ls -ltga", 0};
execve("/bin/sh", args);

The first argument to execve() must be the path to the executable (usually a full path).

人生百味 2024-12-26 07:45:42

shell 需要的符号是 sh -c "command plus argument"。因此,您所做的“解决方法”实际上正是 shell 所要求的。

另一种方法是使用 execvp() 运行 ls

char *args[] = { "ls", "-lgta", 0 };
execvp(args[0], args);
fprintf(stderr, "Oops: failed to find 'ls'\n");
exit(1);

我还需要能够使用正则表达式运行命令,例如 "rm *.c",但这无法在 execve() 内运行(大多数例),所以我尝试通过将整个命令集传递给“sh -c”来解决该故障。有什么想法吗?

如果您想要元字符扩展,则必须调用 shell 来执行此操作(或编写等效代码来执行此操作 - 这是可能的,并且对于标准 POSIX 函数来说并不难做到)。

要运行“rm *.c”,请使用:

char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execv(args[0], args);

或者,如果您有一个需要专门传递的环境(我假设它是由 envp 指向的):

char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execve(args[0], args, envp);

Don'不要忘记 exec* 函数调用后的错误处理;它可能会失败。

The notation the shell expects is sh -c "command plus arguments". So, what you're doing as a 'workaround' is in fact what the shell demands.

The alternative is to use execvp() to run ls:

char *args[] = { "ls", "-lgta", 0 };
execvp(args[0], args);
fprintf(stderr, "Oops: failed to find 'ls'\n");
exit(1);

I also need to be able to run commands with regular expressions, such as "rm *.c", but that fails to run within execve() (most cases), so I am attempting to work around that failure by passing the entire command set to "sh -c" instead. Any ideas?

If you want metacharacter expansion, you have to invoke the shell to do it (or write equivalent code to do it - which is possible and not too dreadfully hard to do with standard POSIX functions).

To run 'rm *.c', use:

char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execv(args[0], args);

Or, if you have an environment you need to pass specifically (I assume it is pointed to by envp):

char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execve(args[0], args, envp);

Don't forget the error handling after the exec* function call; it can fail.

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