2016-05-12 2 views
0

Я хотел бы поместить вывод из сценария bash (sc.sh), который находится в том же каталоге, что и эта программа, и который содержит строку ниже, на вход программы C (cprog) ; выполнение cprog работает, но я не знаю, почему скрипт Баш не запускается:Fork exec и pipe с скриптом 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; 
} 
+2

Szymon, вы должны рассмотреть возможность использования отступов. :) – ZbyszekKr

+1

Вы должны проверить возвращаемые значения вызовов функций. –

+1

Вам нужно 'bash -c'. – EOF

ответ

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; 
} 

Я использовал простую программу на с, как 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 не существует.

+0

Спасибо, мне удалось исправить проблему, закрыв эти дескрипторы файлов, а также переписав cprog. Ваш код был действительно полезен. – Szymon