Не могу использовать именованный канал из C для связи со сценарием оболочки

У меня есть программа на C, как это так (скопировано изВот):

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

и скрипт оболочки вот так:

echo < testpipe

Как только я выполняю программу на C, оператор echo возвращается, ноWe are not alone не печатается. Я также попытался создать канал из командной строки, и сmknod вместо этого, и это не имеет значения. Почему это не работает?

РЕДАКТИРОВАТЬ:

Многие люди указали, что проблема сecho а не сCпроблема в том, что мне нужно работать с чем-то вродеecho (omxplayer собственно, так как я выдаю на него команды управления видео, т.е.p для паузы илиq для выхода). Поэтому я был бы признателен за некоторые ответы, показывающие, как изменить код C, чтобы он работал сecho заявление, а не наоборот

РЕДАКТИРОВАТЬ:

Я не включил полный код, поскольку он используетomxplayer и довольно большой, но некоторые пользователи просили об этом, поэтому здесь как можно меньше этого 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;

Как я уже говорил, программа никогда не завершится, поэтому просто нажмите Ctrl + C}

Изменить 3:

Хорошо, я делаю успехи, кажется, что то, что вы даете каналу, и то, что вы получаете, не одно и то же, запустите этот скрипт и наблюдайте:

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

РЕДАКТИРОВАТЬ 4:

Я.Ф. Себастьян задал несколько хороших вопросов, это ответ на эти вопросы. В конечном итоге я пытаюсь синхронизировать 2 или более экземпляров omxplayer, воспроизводящих один и тот же фильм, на 2 или более малиновых писах.omxplayer-синхронизации пытается достичь этого, но это не точно, он написан на Python, который не подходит для этого, и его подход, IMO, не очень хороший. Я пробираюсь по пищевой цепи, пробуя самые простые решения, чтобы увидеть, являются ли они жизнеспособными. От самого простого к сложному, вот что я уже пробовал (или планирую попробовать)

запускomxplayer экземпляры из оболочки в согласованное время в будущем одновременно:ПРОВАЛзапускomxplayer экземпляры из скрипта Python (более точные по времени) в согласованное время в будущем одновременно:ПРОВАЛзапускomxplayer экземпляры из программы на C (даже более точные по времени) в согласованное время в будущем одновременно:ПРОВАЛЗапустите и сразу приостановите, затем отпуститеomxplayer экземпляры из скрипта Python (более точные по времени) в согласованное время в будущем одновременно:ПРОВАЛЗапустить и сразу же приостановить, а затем приостановить (черезecho -n p > namedpipe) omxplayer экземпляры из программы на С (более точные по времени) в согласованное время в будущем одновременно:ПРОВАЛЗапустить и сразу же приостановить, а затем приостановить (черезwrite ( fd_of_named_pipe, 'p', sizeof ( 'p') );) omxplayer экземпляры из программы на С (более точные по времени) в согласованное время в будущем одновременно:ОЖИДАНИЕПерепишитеomxplayer и модулировать скорость игры, чтобы догнать самого быстрого игрока:БУДУЩЕЕ

В основном, прежде чем вкладывать огромную часть своей жизни в понимание, а затем модифицировать исходный кодomxplayer (7) я хочу посмотреть, если использовать родной язык Cwrite ( fd_of_named_pipe, 'p', sizeof ( 'p') ) операция быстрее, чем егоsystem(echo -n p > namedpipe) вызов, который разветвляет дочерний элемент и вызывает оболочку для записи в именованный канал (моя догадка говорит мне, что это будет намного быстрее, и, надеюсь, более точным). Если это работает и останавливает все экземпляры с точностью до 15 мс, фантастика, мне не придется смотреть наomxpleyerисходный код когда-либо. Если нет, то в крайнем случае я начну изменять исходный код.

Ответы на вопрос(3)

Ваш ответ на вопрос