Nie można użyć nazwanego potoku z C do komunikacji ze skryptem powłoki

Mam taki program w C (skopiowany ztutaj):

#include <fcntl.h>

#define PATH "testpipe"
#define MESSAGE "We are not alone"

int main()
{
   int fd;

   mkfifo ( PATH, 0666 );

   fd = open ( PATH, O_WRONLY );
   write ( fd, MESSAGE, sizeof ( MESSAGE ) );
   close ( fd );

   unlink ( PATH );
   return 0;
}

i skrypt powłoki w taki sposób:

echo < testpipe

Gdy wykonam program C, instrukcja echo zwraca, aleWe are not alone nie jest drukowane. Próbowałem także utworzyć potok z wiersza poleceń izmknod zamiast tego i to nie robi różnicy. Dlaczego to nie działa?

EDYTOWAĆ:

Wiele osób zauważyło, że problem dotyczyecho a nie zC, problem polega na tym, że muszę pracować z czymś takimecho (omxplayer właściwie, ponieważ wydaje mi polecenia sterowania wideo, tj.p na pauzę lubq na zakończenie). Dlatego doceniłbym kilka odpowiedzi wskazujących, jak zmienić kod C, aby działał zecho oświadczenie, w przeciwieństwie do odwrotnie

EDYTOWAĆ:

Nie uwzględniłem pełnego kodu, którego używaomxplayer i jest dość duży, ale niektórzy użytkownicy zażądali tego, dlatego tutaj jest tak minimalnie, jak mógłbym utrzymać to MWE:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define PIPEPATH "testpipe"
#define VIDEOPATH "Matrix.mkv"
#define MESSAGE "q"
#define VIDEOPLAYER "omxplayer"

int main()
{
   int fd;
   pid_t pid;
   pid_t wpid;
   int status;
   char shellCmd [ 1000 ];
   struct timespec time1, time2; //used for sleeping

   //Make pipe BEFORE forking
   mkfifo ( PIPEPATH, 0666 );

   if ( ( pid = fork () ) < 0 )
   {
      perror ( "Fork Failed\n" );
      return -1;
   }
   else if ( pid == 0 )
   { //first child keeps pipe open
      sprintf ( shellCmd, "tail -f /dev/null > %s", PIPEPATH );
      if ( system ( shellCmd ) == -1 )
      {
         printf ( "Error: %s\n", shellCmd );
         fflush(stdout);
      }
   }
   else{
      time1.tv_sec = 1L; //sleep for 1 second to let first child issue its command
      time1.tv_nsec = 0L; //Dont worry about milli seconds

      nanosleep ( &time1, &time2 );

      if ( ( pid = fork () ) < 0 )
      {
         perror ( "Fork Failed\n" );
         return -1;
      }
      else if ( pid == 0 )
      { //second child launches the movie
         sprintf ( shellCmd,  "cat %s | %s %s 2>&1 > /dev/null", PIPEPATH, VIDEOPLAYER,  VIDEOPATH );
         if ( system ( shellCmd ) == -1 )
         {
            printf ( "Error: %s\n", shellCmd );
            fflush(stdout);
         }
      }
      else
      {
         if ( ( pid = fork () ) < 0 )
         {
            perror ( "Fork Failed\n" );
            return -1;
         }
         else if ( pid == 0 )
         { //third child waits 5 seconds then quits movie
            time1.tv_sec = 5L; //sleep for 5 seconds
            time1.tv_nsec = 0L; //Dont worry about milli seconds

            nanosleep ( &time1, &time2 );

            printf ( "Sleep over, quiting movie\n");
            fflush(stdout);

            fd = open ( PIPEPATH, O_WRONLY );
            write ( fd, MESSAGE, sizeof ( MESSAGE ) );
            close ( fd );
         }
      }
   }

   //Note the first child will never exit as it is a blocking shell script
   while ( ( wpid = wait ( &status ) ) > 0 )
   {
      printf ( "Exit status of %d was %d (%s)\n", ( int ) wpid, status, ( status == 0 ) ? "accept" : "reject" );
      fflush(stdout);
   }

   unlink ( PIPEPATH );

   return 0;

Jak już wspomniałem, program nigdy się nie zakończy, więc po prostu wystaw Ctrl + C}

Edytuj 3:

Ok robię postępy, wydaje się, że to, co dajesz fajce i to, co otrzymujesz, nie jest tym samym, uruchom ten skrypt i obserwuj:

#include <stdio.h>
#include <fcntl.h>
#define PIPE_PATH "testpipe"

int main( int argc, char *argv[] ) {
   int fd;
   FILE *fp;
   char c;

   if ( atoi ( argv [ 1 ] ) == 1 )
   {
      printf ("Writer [%s]\n", argv[1]);

      mkfifo ( PIPE_PATH, 0666 );

      fd = open ( PIPE_PATH, O_WRONLY );
      c = getchar();
      write(fd, c, 1);

      close(fd);
   }
   else if ( atoi ( argv [ 1 ] ) == 2 )
   {
      printf ( "Reader [%s]\n", argv[1] );

      fp = fopen( PIPE_PATH, "r" );
      c = getc ( fp );
      putchar ( c );

      printf ( "\n" );
      fclose ( fp );

      unlink( PIPE_PATH );
   }

   return 0;
}

EDYTUJ 4:

J.F. Sebastian zadał kilka dobrych pytań, jest to odpowiedź na te pytania. Ostatecznie staram się zsynchronizować 2 lub więcej przypadków omxplayera grającego ten sam film na 2 lub więcej pisankach malinowych.omxplayer-sync próbuje to osiągnąć, ale nie jest dokładny, jest napisany w Pythonie, który nie jest do tego odpowiedni, a jego podejście to, IMO, nie jest dobre. Pracuję nad łańcuchem żywnościowym, wypróbowując najprostsze rozwiązania, aby sprawdzić, czy są one opłacalne. Od najłatwiejszego do najtrudniejszego, oto co próbowałem do tej pory (lub planuję spróbować)

Uruchomićomxplayer instancje z powłoki w uzgodnionym czasie w przyszłości w tym samym czasie:ZAWIEŚĆUruchomićomxplayer instancje ze skryptu Pythona (bardziej dokładne w czasie) w uzgodnionym czasie w przyszłości w tym samym czasie:ZAWIEŚĆUruchomićomxplayer instancje z programu C (nawet bardziej dokładne w czasie) w uzgodnionym czasie w przyszłości w tym samym czasie:ZAWIEŚĆUruchom i natychmiast wstrzymaj, a następnie wyłączomxplayer instancje ze skryptu Pythona (bardziej dokładne w czasie) w uzgodnionym czasie w przyszłości w tym samym czasie:ZAWIEŚĆUruchom i natychmiast wstrzymaj, a następnie wyłącz pauzę (przezecho -n p > namedpipe) omxplayer instancje z programu C (dokładniejsze w czasie) w uzgodnionym czasie w przyszłości w tym samym czasie:ZAWIEŚĆUruchom i natychmiast wstrzymaj, a następnie wyłącz pauzę (przezwrite ( fd_of_named_pipe, 'p', sizeof ( 'p') );) omxplayer instancje z programu C (dokładniejsze w czasie) w uzgodnionym czasie w przyszłości w tym samym czasie:W OCZEKIWANIUReimplementomxplayer i moduluj prędkości gry, aby dogonić najszybszego gracza:PRZYSZŁOŚĆ

Przed zainwestowaniem ogromnej części mojego życia w zrozumienie, a następnie modyfikację kodu źródłowegoomxplayer (7) Chcę zobaczyć, czy używam natywnego języka Cwrite ( fd_of_named_pipe, 'p', sizeof ( 'p') ) operacja jest szybsza niż jejsystem(echo -n p > namedpipe) wywołanie, które rozwidla dziecko i wywołuje powłokę do zapisu w nazwanym potoku (moje przeczucie mówi mi, że będzie dużo szybsze i miejmy nadzieję, że będzie dokładniejsze). Jeśli to zadziała i cofnie wszystkie wystąpienia do 15ms, fantastycznie, nie będę musiał na to patrzećomxpleyerkod źródłowy kiedykolwiek. Jeśli nie, w ostateczności zacznę modyfikować kod źródłowy.

questionAnswers(3)

yourAnswerToTheQuestion