【问题标题】:Using pipes to redirect the output from 'seq' to the input of 'awk'使用管道将输出从“seq”重定向到“awk”的输入
【发布时间】:2020-05-08 18:35:03
【问题描述】:

在一个子进程中,我调用seq1 作为第一个参数,第一个命令行参数作为第二个参数。然后我继续使用seq 的标准输出作为第二个命令awk 的输入。该命令将第二个命令行参数作为参数。错误检查与此任务无关,因此请专注于功能。

最后awk 的输出应该打印在标准输出上。

它应该模拟类似:seq 1 10 | awk {printf}

这是我走了多远,但我没有得到任何输出:

#define READ 0
#define WRITE 1

int main(int argc, char *argv[]) {

int fd1[2];

if (pipe(fd1)==-1){ 
    fprintf(stderr, "Pipe Failed"); 
    return -1; 
}

int pidSeq = fork();
if(pidSeq == 0){
    close(fd1[READ]);
    dup2(fd1[WRITE], 1);
    close(fd1[WRITE]);
    execl("seq", "seq", "1", argv[1], NULL);
}
else if(pidSeq > 0){
    close(fd1[WRITE]);
    dup2(fd1[READ], 0);
    close(fd1[READ]);
    execl("awk", "awk", argv[2], NULL);
}

return 0;
}

【问题讨论】:

  • 如果您遇到问题,错误检查始终很重要。如果你没有问题,你有时可以在没有错误检查的情况下生存。如果您有问题,可能问题是您没有检查的错误之一。
  • 我想了解如何将一个命令的输出传递给另一个命令的输入的原理。就那么简单。我知道在编写真正的应用程序时,错误检查很重要,但我不希望这里的答案偏离我正在努力的功能点。
  • 我会再说一遍,因为我认为您没有第一次阅读我的评论:如果您有问题,错误检查总是很重要的。如果你没有问题,你有时可以在没有错误检查的情况下生存。如果您有问题,可能问题是您没有检查的错误之一。
  • 也许问题不是因为错误。但也许问题是您没有检查的错误之一。
  • 那么我的示例中的功能过程对吗?如果您了解 Unix 管道和 c 编程,您应该能够告诉我我对这项任务的想法是否正确,不是吗?这将很有帮助,因为如果功能过程是正确的,那么我们可以查看错误检查。如果功能过程已经出错,我们不需要浪费时间检查错误,因为整个程序不会做它应该做的事情。

标签: c unix process pipe posix


【解决方案1】:

使用execlp() 而不是execl()

正如所写,它仅在当前目录包含seqawk 时才有效。

请注意,如果您在 execl() 函数返回时报告了错误(并且它们仅在错误时返回;如果成功则它们不会返回),那么您无需询问就知道出了什么问题。

这是您的代码的固定版本。它使用我在 GitHub 上的 SOQ(堆栈溢出问题)存储库中提供的一些代码,作为 src/libsoq 子目录中的文件 stderr.cstderr.h。这简化了错误报告。

#include <stdio.h>
#include <unistd.h>
#include "stderr.h"

#define READ 0
#define WRITE 1

int main(int argc, char *argv[])
{
    err_setarg0(argv[0]);
    if (argc != 3)
        err_usage("max 'awk script'");

    int fd1[2];
    if (pipe(fd1) == -1)
        err_syserr("failed to create a pipe: ");

    int pidSeq = fork();
    if (pidSeq == 0)
    {
        close(fd1[READ]);
        dup2(fd1[WRITE], 1);
        close(fd1[WRITE]);
        execlp("seq", "seq", "1", argv[1], NULL);
        err_syserr("failed to exec 'seq': ");
    }
    else if (pidSeq > 0)
    {
        close(fd1[WRITE]);
        dup2(fd1[READ], 0);
        close(fd1[READ]);
        execlp("awk", "awk", argv[2], NULL);
        err_syserr("failed to exec 'awk': ");
    }
    else
        err_syserr("failed to fork(): ");

    return 0;
}

它是从seq-awk59.c编译成seq-awk59然后运行为:

$ seq-awk59 15 '{sum += $1}END{print sum}'
120
$

我首先使用带有execl() 的版本而不是execlp()。我得到的输出是:

$ seq-awk59 15 '{sum += $1}END{print sum}'
seq-awk59: failed to exec 'awk': error (2) No such file or directory
seq-awk59: failed to exec 'seq': error (2) No such file or directory
$

滥用程序会产生使用信息:

$ seq-awk59 a b c
Usage: seq-awk59 max 'awk script'
$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-19
    • 2016-10-21
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    相关资源
    最近更新 更多