exec()C中的任何命令

时间:2011-11-11 03:32:09

标签: c linux shell execvp

在C中说,我想在任何字符串命令上调用execvp()。命令可以是:

char command[] = "ls -l";
char command[] = "rm *.txt";
char command[] = "cat makefile";

我想将此命令变量放在execvp()中。因此,exec()风格的函数可以使用任何类型的任意命令运行。

我该怎么做?感谢。

注意:不允许system()

5 个答案:

答案 0 :(得分:8)

如果 要调用execvp(),那么您需要将这些字符串拆分为可执行文件名和参数数组(第一个是程序的“名称”)最后一个是NULL指针。)

这意味着:

char cmd1[] = "ls";  char *args1[] = {"ls", "-l", NULL};
char cmd1[] = "rm";  char *args1[] = {"rm", "*.txt", NULL}; // but see
                                                            // globbing below.
char cmd1[] = "cat"; char *args1[] = {"cat", "makefile", NULL};

这是一项非常重要的练习,特别是如果你想允许引用,整合,转义等等。

引用意味着您必须小心使用以下命令:

rm "file with spaces.txt"

因为你不能简单地打破空格 - 你必须解释命令中的项目与shell一样。简单地打破空格会给你一个命令,上面的字符串有三个参数,而不是正确的。

通过通配,我的意思是你几乎肯定会遇到像*.txt这样的问题,因为它通常是扩展这些参数的 shell 。将其直接传递给execvp()将导致单个参数字面为*.txt,而不是与当前目录中的所有文本文件匹配的许多参数。

引用意味着您必须处理以下内容:

ls -l "file with spaces and \" quote in it"

这将使您的解析器更加复杂。

不要误会我的意思,可以这么做,但是使用system()可能会更容易看到。

如果您仍在考虑使用execvp()路线,则必须:

  • 将字符串拆分为单独的标记(相当难,因为你必须处理引号和转义)。
  • glob所有参数,意味着那些带有通配符的那些(并且只有那些因为在引号内没有被转义或保护的)被扩展为多个参数。
  • 构造参数数组,前面是命令,最后是NULL。
  • 使用参数作为该数组中的第一个元素和数组的地址来调用execvp()

答案 1 :(得分:2)

不,exec系列函数不会像system那样使用单个字符串命令行。相反,它使用argv - 类似的字符串数组:

char *command = "/path/to/command";
char *arguments[] = { "command", "first argument", "second argument", NULL };
execvp(command, arguments);

请注意,arguments数组中的第一个条目是命令本身,并且该数组由NULL终止。

您是否查看了手册页?

答案 2 :(得分:2)

要使用任何execve样式的函数,您需要自己解析命令行并构建一个argv向量。函数采用char **,其中最后一个元素为null - 您需要为所有这些分配足够的内存。然后你的execve式调用应该有效。

(p.s。你没有提到关于fork的任何事情......)

答案 3 :(得分:1)

为了拥有“*”“>”,“<”,“&”等内容要工作,你需要执行“/ bin / sh”并传入命令行作为参数。所以,它归结为标记你的字符串。

答案 4 :(得分:1)

这里需要做的是让shell解析命令。所以考虑一下:

/bin/sh -c 'rm *.txt'

这应该让你朝着正确的方向前进。 :)