【问题标题】:Problems with "sh -c" not accepting extra arguments, UNIX, using execve() [closed]“sh -c”不接受额外参数的问题,UNIX,使用 execve() [关闭]
【发布时间】:2012-01-12 10:45:32
【问题描述】:

我正在尝试了解如何正确使用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" 的文件/脚本

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

【问题讨论】:

  • 你试过2: ls -ltga吗?

标签: bash unix arguments sh execve


【解决方案1】:

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

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

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

【讨论】:

  • 当我不使用引号时,命令的所有参数都会被忽略,无论是在 shell 内部还是在 execve 中。
  • @StefanZuefeldt:shell 使用引号对参数进行“分组”。 execve 不需要;分组是隐式处理的,每个参数都是一个单独的数组元素。通过execve"ls -ltga" 指定为参数之一就像将'"ls -ltga"' 指定为shell 内的参数之一。
  • 虽然从技术上讲这是解决我问题的答案,但这里的每个答案都非常有帮助!非常感谢大家!
【解决方案2】:

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*函数调用后的错误处理;它可能会失败。

【讨论】:

  • 我还需要能够运行带有正则表达式的命令,例如“rm *.c”,但它无法在 execve 中运行(大多数情况下),所以我正在尝试解决这个问题通过将整个命令集传递给“sh -c”来失败。有什么想法吗?
猜你喜欢
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2012-12-06
  • 1970-01-01
相关资源
最近更新 更多