将参数传递给execl

时间:2013-03-23 11:38:10

标签: unix posix

我想在Unix终端中创建自己的管道(只是为了练习)。它应该使应用程序在这样的引号中执行:

  

管道“ls -l”“grep”....

我知道我应该使用fork(),execl()(exec *)和api重定向stdin和stdout。但有没有替代execl使用一个参数执行带有参数的应用程序,其中包含应用程序路径和参数?有没有办法不手动解析“ls -l”,而是将其作为一个参数传递给execl?

2 个答案:

答案 0 :(得分:4)

如果你只有一个命令行而不是参数向量,那么让shell为你做解析:

execl("/bin/sh", "sh", "-c", the_command_line, NULL);

当然,不要让不受信任的远程用户输入到此命令行。但是,如果您要处理不受信任的远程用户输入,那么您应该尝试按照exec[vl]的正常用法,将实际的隔离参数列表传递给目标应用程序,而不是命令行。

答案 1 :(得分:2)

实际上,只有在编译时知道命令的参数个数时,才能真正使用execl()。在shell中,您通常会使用execv()execvp()代替;这些可以处理要执行的命令的任意数量的参数。理论上,在给出命令的路径名时使用execv(),而在{1}}(对命令执行基于PATH的搜索)时使用execvp()。但是,execvp()处理“路径给定”的情况,因此只需使用execvp()

所以,对于你的pipeline命令,你最终会得到一个孩子使用相当于的东西:

char *args_1[] = { "ls", "-l", 0 };
execvp(args_1[0], args_1);

另一个孩子最终会使用相当于:

的东西
char *args_2[] = { "grep", "pattern", 0 };
execvp(args_2[0], args_2);

当然,除了您已经从命令行参数创建了这些字符串,而不是通过初始化创建了这些字符串,如图所示。请注意,grep需要搜索模式。

您仍然需要解决管道问题。确保关闭足够的管道文件描述符。当您dup()dup2()管道连接到标准输入或标准输出时,您将关闭pipe()函数中的两个文件描述符。