C程序中的I / O重定向

时间:2012-08-13 02:44:44

标签: redirect io

我想在C程序中实现一个简单的“cat file1> file1”命令。我尝试了以下方法,但它不起作用......

main () {
    pid_t pid;
    FILE *ip, *op;
    char *args[3];
    printf("Name of the executable program\n\t");
    scanf("%s", &name[0]); // I entered cat here
    printf("Name of the input file\n\t");
    scanf("%s", &name[1]); //file1.txt
    printf("Name of the output file\n\t");
    scanf("%s", &name[0]); //file2.txt
    pid = fork();
    if(pid == -1)
        perror("fork() error");
    else if(pid > 0)
        waitpid(-1, NULL, 0);
    else if (pid == 0) {
        op = fopen(name[2], "w");
        close(1);
        dup(op);
        execlp(name[0], name[1], NULL);
        }
    return 0;
    }// end of main()

我认为execlp()会运行cat file1.txt并且其输出会重定向到file2.txt,但它不是,我不知道为什么。我该怎么做?

3 个答案:

答案 0 :(得分:1)

scanf("%s", &name[0]); // I entered cat here
printf("Name of the input file\n\t");
scanf("%s", &name[1]); //file1.txt
printf("Name of the output file\n\t");
scanf("%s", &name[0]); //file2.txt

显然,不是实际代码的C& P,name应该是args,最后一个应该是“2”而不是0。

此外,dup适用于文件描述符,而不是FILE *,因此需要查看open而不是fopen,或者从FILE获取fd的任何方法*

答案 1 :(得分:1)

execlp()的第一个参数是要查找的名称;第二个和后面的参数是argv列表,从argv[0]开始。

int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);

对于shell I / O重定向,使用open()打开文件比使用标准I / O(<stdio.h>FILE *)更容易;您还应该关闭在dup()之后打开的文件,尽管使用dup2()更容易。你需要分配空间来读取字符串;在许多系统上,原始代码会崩溃,因为str中的指针不指向任何地方。通常情况下,只有当一切正常时,才能以状态0退出;否则,以非零退出状态退出。

这导致:

#include <fcntl.h>      /* open() */
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>   /* waitpid() */
#include <unistd.h>     /* execlp(), fork(), dup2() */

int main(void)
{
    pid_t pid;
    pid_t corpse;
    int   status;
    char  name[3][50];
    printf("Name of the executable program\n\t");
    if (scanf("%49s", name[0]) != 1)
        return(EXIT_FAILURE);
    printf("Name of the input file\n\t");
    if (scanf("%49s", name[1]) != 1)
        return(EXIT_FAILURE);
    printf("Name of the output file\n\t");
    if (scanf("%49s", name[2]) != 1)
        return(EXIT_FAILURE);
    pid = fork();
    if (pid == -1)
    {
        perror("fork() error");
        return(EXIT_FAILURE);
    }
    else if (pid > 0)
        corpse = waitpid(-1, &status, 0);
    else
    {
        int fd = open(name[2], O_WRONLY|O_CREAT|O_EXCL, 0644);
        if (fd < 0)
        {
            fprintf(stderr, "Failed to open %s for writing\n", name[2]);
            return(EXIT_FAILURE);
        }
        dup2(fd, 1);
        close(fd);
        execlp(name[0], name[0], name[1], NULL);
        fprintf(stderr, "Failed to exec %s\n", name[0]);
        return(EXIT_FAILURE);
    }
    return(corpse == pid && status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}

答案 2 :(得分:0)

你必须使用fork()一个进程并将它的文件描述符重新分配给以前(手动)open()'ed文件,或者使用system()调用让shell为你处理它。