叉子exec和管道与bash脚本

时间:2016-05-12 13:45:49

标签: c

我想将bash脚本(sc.sh)的输出放在C程序的输入端(cprog,该脚本与此程序位于同一目录中并且包含下面一行);执行cprog有效,但我不知道为什么bash脚本没有启动:

timeout 5 cat /dev/urandom

这是主程序:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char* argv[])
{
    int fd[2];
    pid_t pid1, pid2;
    char * input[] = {"/bin/bash", "sc.sh", argv[1], NULL}; 
    char * output[] = {"./cprog", argv[1], NULL};

    pipe(fd);

    pid1 = fork();
    if (pid1 == 0) {
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        execv(input[0], input);   
        return 1;
    }

    pid2 = fork();
    if (pid2 == 0) {
        dup2(fd[0], STDIN_FILENO);
        close(fd[1]);
        execv(output[0], output);
        return 1;
    }

    close(fd[0]);
    close(fd[1]);
    waitpid(pid1, NULL, WNOHANG);
    waitpid(pid2, NULL, WNOHANG);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

我修改了你的程序以报告错误并实际等待孩子们死亡,如下所示:

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    if (argc > 2)
        fprintf(stderr, "Excess arguments ignored\n");
    int fd[2];
    pid_t pid1, pid2;
    char * input[] = {"/bin/bash", "sc.sh", argv[1], NULL}; 
    char * output[] = {"./cprog", argv[1], NULL};

    pipe(fd);

    pid1 = fork();
    if (pid1 == 0) {
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        close(fd[1]);
        execv(input[0], input);   
        perror(input[0]);
        return 1;
    }

    pid2 = fork();
    if (pid2 == 0) {
        dup2(fd[0], STDIN_FILENO);
        close(fd[0]);
        close(fd[1]);
        execv(output[0], output);
        perror(output[0]);
        return 1;
    }

    close(fd[0]);
    close(fd[1]);
    int status1;
    int corpse1 = waitpid(pid1, &status1, 0);
    printf("PID %d: %d (0x%.4X)\n", pid1, corpse1, status1);
    int status2;
    int corpse2 = waitpid(pid2, &status2, 0);
    printf("PID %d: %d (0x%.4X)\n", pid2, corpse2, status2);
    return 0;
}

我使用了一个简单的C程序cprog

#include <stdio.h>

int main(void)
{
    int c;
    unsigned sum = 0;
    unsigned cnt = 0;
    while ((c = getchar()) != EOF)
        sum += c, cnt++;
    printf("sum of bytes: %u\n", sum);
    printf("num of bytes: %u\n", cnt);
    return 0;
}

在命令行上进行测试得出:

$ bash sc.sh | cprog
sum of bytes: 325895667
num of bytes: 69926912
$

运行主程序(p19创建的p19.c)产生了:

$ ./p19
sum of bytes: 372818733
num of bytes: 70303744
PID 28575: 28575 (0x7C00)
PID 28576: 28576 (0x0000)
$

退出状态显示timeout退出状态124,这是命令超时时GNU文档作为退出状态。

因此,在我的环境再现中,您提供的代码可以正常工作。这表明您的环境没有像您想象的那样设置。也许sc.sh脚本不存在。