在子进程中,我调用 seq
,其中 1
作为第一个参数,第一个命令行参数作为第二个参数。然后,我继续使用 seq
的标准输出作为第二个命令 awk
的输入。该命令获取第二个命令行参数作为参数。错误检查与此任务无关,因此请专注于功能。
最后,awk
的输出应该打印在 stdout 上。
它将模拟如下内容: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;
}
最佳答案
使用execlp()
而不是execl()
。
正如所写,它仅在当前目录同时包含 seq
和 awk
时才有效。
请注意,如果您在 execl()
函数返回时报告了错误(它们仅在出错时返回;如果成功则不会返回),那么您就会知道发生了什么错了不用问。
这是代码的固定版本。它使用我的 SOQ 中提供的一些代码(堆栈溢出问题)GitHub 上的存储库为 src/libsoq 中的文件 stderr.c
和 stderr.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'
$
关于c - 使用管道将输出从 'seq'重定向到 'awk'的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59862450/