명명된 파이프에 지속적으로 쓰기

명명된 파이프에 지속적으로 쓰기

해결할 수 없는 두 개의 명명된 파이프와 관련된 문제가 있습니다. 기본적으로 내가 제어할 수 없는 두 가지 프로세스가 있습니다. 명명된 파이프( )를 통해 통신합니다 mknod pipe p. 프로세스 1은 NMEA0183 형식으로 메시지를 출력하는 GPS 드라이버입니다. 프로세스 2는 NMEA0183 데이터를 읽어 GPS에서 위치와 날짜/시간을 얻는 내비게이션 애플리케이션입니다. 이 데이터를 조정해야 합니다(이유: Google에서 WNRO를 검색하거나 문의).

  1. 첫 번째 프로세스는 1초 간격으로 /var/run/one.pipe에 지속적으로 데이터(~5-8줄의 텍스트)를 쓰고 읽을 때(?)까지 그대로 둡니다.

  2. 두 번째 프로세스는 명명된 파이프에서 이 데이터를 읽는 것입니다. 읽을 명명된 파이프의 이름을 변경할 수 있습니다. /var/run/two.pipe로 변경했습니다.

최종 목표는 one.pipe에서 데이터를 읽고 일부 처리를 수행한 다음 이를 Two.pipe에 전달하는 것입니다. 하지만 그동안 테스트 목적으로 one.pipe에서 Two.pipe로 데이터를 하나씩 복사해 보았습니다. 이 (더 쉬운?) 작업을 완료할 수 있을 때까지 이 전체 프로세스에 시간을 낭비하는 것은 불가능하다고 생각합니다.

매우 간단한 쉘 스크립트가 작동합니다: copy.sh

#!/bin/sh
cat one.pipe > two.pipe &

이제 소스 프로세스에서 작성된 일부 데이터를 캡처 하고 읽기 프로세스가 읽을 수 있도록 one.pipe수동으로 작성하려고 합니다 .two.pipe

#!/bin/sh

while true; do
  echo "\$GPGGA,,,,,,,,*12" > two.pipe
  echo "\$GPGSA,,,,,,,,*23" > two.pipe
  echo "\$GPRMC,,,,,,,,*34" > two.pipe
  echo "\$GPGSV,,,,,,,,*45" > two.pipe
  echo "\$GPGSV,,,,,,,,*56" > two.pipe
  echo "\$GPGSV,,,,,,,,*67" > two.pipe
  # checksums (*xx) are just examples here
  sleep 1 > two.pipe
done

이제 이것은 잘 작동하지 않습니다. cat one.pipe와 비교해 보면 의 메시지가 "쌓이는" 것이 아니라 작성된 원래 프로세스에서 쌓이고 있다는 cat two.pipe것을 알 수 있습니다 . 예를 들어, 스크립트를 시작하면 명명된 파이프에 쓰고 계속해서 작성해야 합니다. 파이프를 읽는 데 사용하면 지금까지의 모든 데이터가 출력됩니다(fifo 버퍼가 아직 채워지지 않았다고 가정). 결국은 먼저 들어간 것이 먼저인 것 아닌가요?two.pipeone.pipecat

또한, 이제 고양이는 겉보기에 무작위로 멈추는 경우가 많습니다. 마지막으로, two.pipe데이터를 제대로 처리하지 못하거나 스크립트가 종료되는 프로세스를 읽는 과정을 제어할 수 없습니다 .

무한 루프가 포함되어 있음에도 스크립트가 종료되는 이유를 이해하지 못합니까? !

여기서 무엇을 모니터링하고 있나요? 셸에서 작성하는 것이 불가능하다면 C도 옵션입니다.

답변1

while true; do
  echo "\$GPGGA,,,,,,,,*12" > two.pipe
  echo "\$GPGSA,,,,,,,,*23" > two.pipe
  ...

... > two.pipe스크립트의 각 줄이 열리고폐쇄fifo 를 two.pipe닫으면 파이프의 다른 쪽 끝에서 읽기가 파일 끝을 반환하고 cat종료될 수 있습니다.

FIFO를 처음부터 여는 것을 추천합니다한 번전체 스크립트의 경우 exec:

#!/bin/sh

exec > two.pipe

while true; do
  echo "\$GPGGA,,,,,,,,*12"
  echo "\$GPGSA,,,,,,,,*23"
  ...
  sleep 1
done

예를 들어, fifo의 양쪽 끝을 동일한 핸들로 열어서 fifo를 "고정"할 수 있습니다.

exec 7<>two.fifo

이 작업을 수행하는 프로세스가 종료되지 않고 파일 설명자가 닫히지 않는 한 7, 다른 모든 핸들이 해당 파일 설명자를 처리하는 동안 해당 파일 설명자에서 읽는 프로세스가 파일 끝을 얻지 못한다는 것이 보장됩니다.글쓰기SIGPIPEend가 닫히고 여기에 쓰는 프로세스는 다른 모든 핸들이 이를 가리키는 동안 종료되지 않습니다.읽다끝이 닫혀 있습니다.

또한 지정된 fifo의 양쪽 끝을 동시에 열어도 차단되지 않습니다.

관련 정보