简体   繁体   English

调用execvp()内部的重定向无法正常工作

[英]Redirection inside call to execvp() not working

I've been implementing a small program that executes a given command using execvp(). 我一直在实现一个使用execvp()执行给定命令的小程序。 It works fine when not using redirection, but when I run a command such as: 不使用重定向时它工作正常,但是当我运行如下命令时:

cat file1.txt > redirected.txt

cat outputs the following error messages and fails: cat输出以下错误消息并失败:

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

I've done some digging around and I'm starting to think that perhaps execvp() isn't allowed to do redirection because it doesn't run in the shell. 我已经做了一些挖掘,我开始认为也许execvp()不允许进行重定向,因为它不在shell中运行。 Does that mean that I would have to manually pick out when redirection occurs and use pipes in my fork/exec code to get around this restriction? 这是否意味着我必须在重定向发生时手动选择并在fork / exec代码中使用管道来解决这个限制? Is there a better way than to use execvp()? 有没有比使用execvp()更好的方法?

Thanks! 谢谢!

Your "small program that executes a given command" is essentially a shell. 您的“执行给定命令的小程序”本质上是一个shell。 Since you are writing a shell, it is your job to implement redirections with whatever syntax you desire. 由于您正在编写shell,因此您可以使用所需的任何语法实现重定向。 The > redirection operator is not a feature of the kernel, it is a shell feature. >重定向运算符不是内核的一个特性,它是一个shell特性。

To implement sh -style redirection, you must parse the command, locate the redirection operators, open the files and assign them to input/output descriptors. 要实现sh样式重定向,必须解析命令,找到重定向运算符,打开文件并将它们分配给输入/输出描述符。 This must be done before calling execvp . 这必须调用execvp 之前完成。 Look up the dup2 system call. 查找dup2系统调用。

You can use system() if you really want to use that sort of syntax. 如果您真的想使用那种语法,可以使用system()。 As you noted, redirection and wildcard expansion and a whole bunch of other things are handled by the shell on Unix-like systems. 正如您所指出的,重定向和通配符扩展以及一大堆其他内容由类Unix系统上的shell处理。

The way to do it with fork looks something like this: 使用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. */
}

It seems like the easiest thing to do is: 看起来最简单的事情是:

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

You can do the same with execvp . 你可以用execvp做同样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM