拆分 Unix 命令以与 exec 一起使用

Xyz*_*yzk 2 c unix ansi exec

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

Kei*_*son 5

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

"/bin/cat file1 file2"
Run Code Online (Sandbox Code Playgroud)

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

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

execl("/bin/cat", "file1", "file2");
Run Code Online (Sandbox Code Playgroud)

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

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

int execv(const char *path, char *const argv[]);
Run Code Online (Sandbox Code Playgroud)

所述argv参数是一个指向到指针到炭,其应指向的数组的第一个元素char*的元素,其中的每一个指向的第一个字符'\0'封端的字符串。

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

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

"/bin/cat file1 file2"
Run Code Online (Sandbox Code Playgroud)

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

"/bin/cat\0file1\0file2\0"
Run Code Online (Sandbox Code Playgroud)

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

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

当然最简单的方法是:

char command[] = "/bin/cat file1 file2";
system(command);
exit(0);
Run Code Online (Sandbox Code Playgroud)

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