C 프로그램에서 생성된 Bash에서 명명된 파이프 사용

C 프로그램에서 생성된 Bash에서 명명된 파이프 사용

상당히 큰 입력이 필요한 C 코드가 있습니다. 각 반복마다 작은 청크를 처리하고 처리된 청크는 컬을 사용하여 S3으로 보내야 합니다. 결국에는 많은 작은 청크가 생성되고 큰 입력이 완전히 처리됩니다. 문제가 있는 부분은 처리된 청크를 개별적으로 S3에 보내는 데 사용하는 명명된 파이프를 호출하는 bash 스크립트 부분입니다.

C에서 bash 스크립트를 호출하고 bash를 사용하여 명명된 파이프의 데이터를 컬링하는 방법은 무엇입니까?

간결함을 유지하기 위해 코드의 관련 부분만 공유하겠습니다.

#define FIFO_NAME "my_fifo"
int i,j,k;
char *d_ptr; //dummy pointer for frame set
int res;
/* create the FIFO (named pipe) */

if (access(FIFO_NAME, F_OK) == -1) {
    res = mkfifo(FIFO_NAME, 0777);
    if (res != 0)
    {
        fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
        exit(EXIT_FAILURE);
    }
}
res = open("test_fifo", O_WRONLY);
d_ptr=(char *) compressed_queue;
if(m_ptr-m_ptr_initial==0 | m_ptr-m_ptr_initial>MAX_MESSAGE_LENGTH-FLENGTH*sizeof(float) | number_of_frames>MAX_FRAME_NUMBER)//sends message when the chunk is ready and adds its prefix
{

    for(j=0;j<m_ptr-m_ptr_initial;j++)//sends message as stdout
    {

        /* write to the FIFO */
        write(res, m_ptr_initial[j], sizeof(char));

    }
    if (res != -1)
        (void)close(res);

또한 bash 스크립트는 다음과 같습니다.

#!/bin/bash
while true
do
    TIMER=renesas-$(date +"%H-%M-%S").txt
    echo $TIMER
    ./Compression
    my_fifo| curl -X PUT --data-binary @- 54.231.19.24/{somePublicBucket}/device1/${TIMER}
done

답변1

코드에 두 가지 오류가 있습니다.

  1. write(…, sizeof(char));원하는 버퍼 크기가 아닌 "sizeof(char)" 바이트(= 대부분 1 또는 2바이트)만 FIFO에 씁니다.

  2. my_fifo |cat적어도 필요한 경우 FIFO에서 데이터를 읽지 않습니다 .

스크립트가 데이터를 읽을 때까지(또는 그 반대) 호출이 write차단되므로 쓰기 작업과 스크립트 실행을 두 개의 서로 다른 프로세스나 스레드에 두는 것이 좋습니다(비차단 쓰기와 같은 다른 가능성도 있습니다. 의도한 디자인에 따라 완전히 다릅니다). 다음 예에서는 fork단순화를 위해 시스템 호출을 사용하여 원리를 보여줍니다.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>

#define FIFO_NAME "./my_fifo"

int main() {
    int res, fifo, pid;
    char *str = "Hello World!\n";

    /* Fork this process into a reader and a writer */
    fprintf(stderr, "Forking process\n");
    pid = fork();
    assert(pid >= 0);

    if (pid == 0) {
        /* The reader calls a shell script supposed to read the data from the FIFO */
        printf("Starting shell script\n");
        system("./tst.sh");
    }
    else {
        /* Create FIFO */
        fprintf(stderr, "Creating FIFO\n");
        remove(FIFO_NAME);
        res = mkfifo(FIFO_NAME, 0777);
        assert(res == 0);

        /* Open FIFO */
        fprintf(stderr, "Opening FIFO\n");
        fifo = open(FIFO_NAME, O_WRONLY);
        assert(fifo != 0);

        /* The writer opens the FIFO and writes some data to it */
        printf("Writing to FIFO\n");
        res = write(fifo, str, strlen(str));
        assert(res > 0);
        close(fifo);
    }
}

쉘 스크립트에는 다음 tst.sh이 포함됩니다.

#!/bin/sh
echo "Started shell script"
cat ./my_fifo

C 프로그램의 출력은 다음과 같습니다.

Forking process
Creating FIFO
Opening FIFO
Starting shell script
Started shell script
Writing to FIFO
Hello World!

관련 정보