2

我正在尝试找出如何使用sh -cbash -c正确使用。

我可以轻松地运行一个简单的命令,比如 "sh -c ls"不带参数。

当我尝试添加参数时,问题就来了。要做ls -ltga,我必须做:

sh -c "ls -ltga"

这不会是一个大问题,除非我正在尝试编写自己的小型 shell 程序,并且当我使用时,execve我尝试:

Argument #:  string
         0:  sh
         1:  -c
         2:  "ls
         3:  -ltga"

它给了我一个错误,说它在找到下一个之前达到了 EOF'"'

我也试过:

         0:  sh
         1:  -c
         2:  "ls -ltga"

它返回给我说它找不到名为的文件/脚本"ls -ltga"

有人知道我做错了什么吗?

4

2 回答 2

3

您不应该在execve(). 它应该这样调用:

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

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

于 2011-12-04T02:10:36.370 回答
0

shell 期望的符号是sh -c "command plus arguments". 因此,您作为“解决方法”所做的实际上是 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);

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

于 2011-12-04T02:10:42.747 回答