2

我有一个程序,它从输入中获取命令,然后使用它执行它execl(它必须是来自execvp家庭的功能)。现在,假设输入行是in,我可以简单地使用execl(allBeforeFirstSpaceFromIn, in);,还是必须in分成更小的字符串?如果是这样,我可以简单地将所有空格更改为\0

4

3 回答 3

5

所以你的输入是一个字符串,比如:

"/bin/cat file1 file2"

不,您不能只将一个参数传递"/bin/cat"execl,并"file1 file2"作为另一个参数传递。这将导致/bin/cat尝试打开一个名为file1 file2. 您希望它打开两个文件file1file2,这意味着您需要传递三个单独的参数。

execl可能不适合你正在做的事情。这是一个可变参数函数;要调用它,您必须在编写代码时知道要传递给它的参数数量。所以这:

execl("/bin/cat", "file1", "file2");

应该可以,但是您不能从字符串中构建该调用。

您想改用其中一种execv*()功能。例如:

int execv(const char *path, char *const argv[]);

argv参数是一个指向字符的指针,它应该指向一个元素数组的第一个元素char*,每个元素都指向一个以 - 结尾的字符串的第一个'\0'字符。

因此,您必须构建该指针数组,并将每个指针初始化为指向一个字符串参数。

现在,如果您有一个包含字符串的数组:

"/bin/cat file1 file2"

一种方法是用空字符替换空格:

"/bin/cat\0file1\0file2\0"

(最后一个\0已经在那里)。然后,您可以构造您的数组,char*以便每个元素都指向数组的开头,或者就在'\0'您刚刚创建的字符之一之后。每个这样的指针都是指向字符串的有效指针。

但我不一定会推荐这种方法。如果您的输入字符串碰巧在单词之间包含多个空格(您可能希望将其视为单个空格),或者您想做一些花哨的事情,例如扩展通配符,您将会遇到问题。我建议您自己分配数组并将适当的数据复制到其中。通过重复使用输入字符串节省的空间是不值得的。

当然最简单的方法是:

char command[] = "/bin/cat file1 file2";
system(command);
exit(0);

它将命令字符串传递给/bin/sh,它会为您完成所有工作。但是你不会学习如何使用这些exec*()功能,我认为这是本练习的重点。

于 2013-03-30T00:52:25.070 回答
2

是的,您需要将参数作为单独的字符串传递。

对于execlX函数,您需要将每个参数作为参数传递:

execl(prog, arg1, arg2,...);

对于execvX函数,您需要传递一个 c 风格的字符串数组:

char **argv = /* ... */;
argv[0] = "arg1";
argv[1] = "arg2";
execv(prog, args);

要拆分输入字符串,您可以使用strtok,或者只是执行以下操作:

char **argv = /* malloc stuff */;
char *prev = in;
cnt = 0;
while (in[0]) {
  if (in[0] == ' ') {
    in[0] = 0;
    argv[cnt++] = prev;
    prev = in + 1;
  }
  in++;
}
argv[cnt++] = prev;
argv[cnt]   = NULL;
于 2013-03-30T00:51:31.900 回答
1

There are basically two ways to call exec, either provide all arguments one by one (execl) or provide an array of arguments (execv).

If you provide a long string having all arguments separated with \0 exec will not understand that other arguments exist after the first one.

So you have either to

  • use execl and provide a list of arguments, eg (..., in, in+x, in+y, NULL)
  • or make an array of (char *) strings each of the elements pointing to in, in+x, in+y, ..., and use execv

with x and y (...) being the index in the long string of the arguments, e.g. in being

command\0arg1\0arg2\0
^0       ^8    ^13

x would be 8 and y would be 13. And you could create an array of strings

char *args[] = { in, in+x, in+y, NULL };

then use execv execv(in, args);

于 2013-03-30T00:53:02.900 回答