在C中说,我想在任何字符串命令上调用execvp()
。命令可以是:
char command[] = "ls -l";
char command[] = "rm *.txt";
char command[] = "cat makefile";
我想将此命令变量放在execvp()
中。因此,exec()
风格的函数可以使用任何类型的任意命令运行。
我该怎么做?感谢。
注意:不允许system()
。
答案 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()
路线,则必须:
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'
这应该让你朝着正确的方向前进。 :)