如何使用重定向输出的execlp()

时间:2017-05-27 20:14:55

标签: c unix

我试图在Unix环境下编写使用execlp函数的c程序。

命令是:

 execlp("tsort","tsort","text.txt",">","1.txt",(char *)NULL);
 syserr("execlp");

我总是得到同样的错误。 错误是:

tsort: extra operand `>'

我做错了什么?

1 个答案:

答案 0 :(得分:3)

'>'它不是一个参数,通常由shell解释。如果要在C代码中实现相同的效果,则必须执行shell通常执行的操作:

  1. 打开文件(1.txt)进行写作
  2. fork()新流程
  3. [in child]使用dup2()
  4. 用文件的描述符替换新进程的stdout
  5. [在孩子]执行命令
  6. POSIX的简化示例代码:

    #define _POSIX_C_SOURCE 200101L
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int main(void)
    {
        int outfd = open("1.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644);
        if (!outfd)
        {
            perror("open");
            return EXIT_FAILURE;
        }
        pid_t pid = fork();
        if (pid < 0)
        {
            close(outfd);
            perror("fork");
            return EXIT_FAILURE;
        }
    
        if (pid)
        {
            // child code
            dup2(outfd, 1); // replace stdout
            close(outfd);
    
            // just a "useless cat" for simplicity:
            execlp("cat", "cat", "redir.c", 0);
        }
        else
        {
            // parent code
            close(outfd);
            int status;
            waitpid(pid, &status, 0);
            if (WIFEXITED(status)) return WEXITSTATUS(status);
            else return EXIT_FAILURE;
        }
    }
    

    根据评论:如果您不介意用被叫程序替换您的流程,您甚至不需要分叉并且程序变得非常短:

    #define _POSIX_C_SOURCE 200101L
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int main(void)
    {
        int outfd = open("1.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644);
        if (!outfd)
        {
            perror("open");
            return EXIT_FAILURE;
        }
        dup2(outfd, 1); // replace stdout
        close(outfd);
        execlp("cat", "cat", "redir.c", 0);
    }
    

    这当然是 交互式 shell所做的事情。