在用于创建流程的Windows API中,我们有CreateProcess
个功能。
现在让我们考虑创建进程并运行DIR /X
命令。当然在Windows中没有可执行文件DIR.exe
,我们不能将其传递给CreateProcess
。那该怎么办?
解决这个问题非常简单。我们应该将cmd /C "DIR /X"
(作为第二个参数)传递给CreateProcess
。
现在让我们尝试在unix中执行相同操作(不是DIR /X
,而是使用ls | wc
)。
在unix中,我将使用fork + execvp
创建新进程并执行命令。为什么我希望我的命令为ls | wc
,因为在unix中,ls
,grep
,ps
这样的单个命令是可执行文件,可以单独传递给exec(即不作为参数sh
,bash
,...)。
所以在这里我们似乎可以将"ls | wc"
作为sh
的参数传递。 (即我们可以对sh -c "ls | wc"
进行标记并将其传递给execvp
)。但是Oooops,这不起作用!
char *arg[] = {"sh", "-c", "\"ls | wc\"", NULL};
execvp(arg[0], arg);
那么问题。我该如何解决这个问题?
P.S。
在Windows中,如果安装了cygwin,cmd /C "ls | wc"
可以正常工作。
答案 0 :(得分:5)
您的参数列表必须以NULL指针终止。
char *arg[] = {"sh", "-c", "ls | wc", NULL};
答案 1 :(得分:2)
您不需要转义\"
,这应该可以正常工作:
char *arg[] = {"sh", "-c", "ls | wc", NULL};
"
仅用于shell来区分输入的哪个部分“分组”为参数,但在进行execvp
调用时不需要它们。你可以的效果就像你在shell中输入"ls | wc"
一样,包括双引号(尝试它,你会得到ls | wc: command not found
)。
答案 2 :(得分:2)
在您的示例中使用system()可能会更容易。
答案 3 :(得分:1)
摆脱对sh:
参数的引用char *arg[] = {"sh", "-c", "ls | wc", NULL};
execvp(arg[0], arg);