5

我一直在实现一个使用 execvp() 执行给定命令的小程序。不使用重定向时它工作正常,但是当我运行以下命令时:

cat file1.txt > redirected.txt

cat 输出以下错误信息并失败:

cat: >: No such file or directory
cat: redirected.txt: No such file or directory

我已经做了一些挖掘,我开始认为 execvp() 可能不允许进行重定向,因为它不在 shell 中运行。这是否意味着我必须在重定向发生时手动选择并在我的 fork/exec 代码中使用管道来绕过这个限制?有没有比使用 execvp() 更好的方法?

谢谢!

4

3 回答 3

8

您的“执行给定命令的小程序”本质上是一个外壳。由于您正在编写一个 shell,因此您的工作就是使用您想要的任何语法来实现重定向。>重定向操作符不是内核的一个特性,它是一个 shell 特性。

要实现sh-style 重定向,您必须解析命令、定位重定向运算符、打开文件并将它们分配给输入/输出描述符。这必须在调用之前execvp完成。查找dup2系统调用。

于 2012-12-09T03:19:23.840 回答
6

如果你真的想使用这种语法,你可以使用 system() 。正如您所指出的,重定向和通配符扩展以及一大堆其他事情是由类 Unix 系统上的 shell 处理的。

使用 fork 的方法如下所示:

int kidpid;
int fd = open("redirected.txt", O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0) { perror("open"); abort(); }
switch (kidpid = fork()) {
  case -1: perror("fork"); abort();
  case 0:
    if (dup2(fd, 1) < 0) { perror("dup2"); abort(); }
    close(fd);
    execvp(cmd, args); perror("execvp"); abort();
  default:
    close(fd);
    /* do whatever the parent wants to do. */
}
于 2012-12-09T03:20:48.407 回答
3

似乎最简单的事情是:

execlp( "/bin/sh", "/bin/sh", "-c", "cat file1.txt > redirected.txt", (char *)NULL );

您可以对execvp.

于 2012-12-09T03:32:53.663 回答