추가 읽기

추가 읽기

수동으로 시작하지만 systemd(HOST_TX)에서는 작동하지 않는 일련의 명령이 있습니다.

주인_인수하다:

nc -v -l -p 5006 

Listen[0.0.0.0](시리즈 0, 포트 5006)

주인_송신:

 /opt/sendtofifo.sh > /tmp/tofifo1                    # in a shell
 nc -v -w 3 HOST_RX 5006 < /tmp/tofifo1   # in a second shell

fifo를 사용하지 않는 경우 수동으로 보낼 수 있습니다.

/bin/bash -xc '/opt/sendtofifo.sh | /bin/nc -v -T lowdelay  HOST_RX 5006'

HOST_RX가 수신을 중지하면 두 명령 모두 systemd가 계속 실행되는 대신 /opt/sendtofifo.sh상태를 무시하고 clean 종료됩니다 nc.

다음과 같이 systemd 서비스를 설정해 보십시오.

[Service]
Type=simple
RestartSec=2
ExecStart=/bin/bash -xc '/opt/sendtofifo.sh | /bin/nc -v -T lowdelay  HOST_RX 5006'
Restart=always

이것은 먼저 작동합니다:

root@rx(boot:ro,root:rw):/home/pi# systemctl status  rx_rc.service
● rx_rc.service - RX RC Service
   Loaded: loaded (/etc/systemd/system/rx_rc.service; static; vendor preset: enabled)
   Active: active (running) since Tue 2020-06-09 14:34:52 CEST; 4s ago
 Main PID: 28649 (bash)
   CGroup: /system.slice/rx_rc.service
           ├─28649 /bin/bash -xc /opt/sendtofifo.sh  | /bin/nc -v -T lowdelay  10.11.10.11 5006; exit
           ├─28650 /opt/sendtofifo.sh 
           └─28651 /bin/nc -v -T lowdelay 10.11.10.11 5006

이제 HOST_RX가 연결을 닫으면 다음과 같은 결과를 얻습니다.

● rx_rc.service - RX RC Service
   Loaded: loaded (/etc/systemd/system/rx_rc.service; static; vendor preset: enabled)
   Active: active (running) since Tue 2020-06-09 14:34:52 CEST; 1min 11s ago
 Main PID: 28649 (bash)
   CGroup: /system.slice/rx_rc.service
           ├─28649 /bin/bash -xc /opt/sendtofifo.sh | /bin/nc -v -T lowdelay  10.11.10.11 5006; exit
           └─28650 /opt/sendtofifo.sh

nc서비스가 실패하면 다시 시작할 수 있는 방법이 있나요?

댓글에 대한 응답

/opt/sendtofifo.sh 프로세스의 strace 출력

nanosleep({tv_sec=0, tv_nsec=200000000}, NULL) = 0
write(1, "\0\0\f\0\4\200\0\0\30\0\0\0\264\277\0\0\271\315\6\0002\364\301\22\257\4 \0\315", 29) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=1589, si_uid=0} ---
nanosleep({tv_sec=0, tv_nsec=200000000}, NULL) = 0

답변1

뻔하지만 틀린 대답은 "하지만SIGPIPE ~ 할 것이다프로그램이 종료되기 때문에 프로그램이 종료되므로 SIGPIPE이를 Restart=always설정하면 프로그램이 다시 시작됩니다. ".

SIGPIPEsystemd는 서비스를 실행할 때 기본적으로 신호를 무시하기 때문에 이것은 잘못된 것입니다 . 따라서 서비스 프로세스와 해당 하위 프로세스(이 경우 스크립트를 해석하는 셸)는 모든 SIGPIPEs를 무시하고 계속 진행합니다.

왜 systemd가 이것을 하는가? systemd-journald이전 버전의 systemd에서는 systemd-journald충돌이 발생하거나 종료될 때 표준 출력 및 표준 오류가 전송된 모든 서비스가 를 받게 되었기 때문 입니다 SIGPIPE. 무시하지 않으면 시스템의 거의 모든 서비스가 Closing 이 됩니다 . systemd-journald말할 것도 없이 불행한 상황. 시스템에 속한 사람들은 daemontools에서 교훈을 얻지 못했습니다. daemontools는 svscan"메인" 서비스와 "로그" 서비스 사이의 파이프에 대한 열린 파일 설명자를 유지하여 "메인" 서비스가 " SIGPIPE로그" 오류가 발생할 때 허위 사례를 얻지 못하도록 합니다. " 서비스 . 어떤 이유로든 서비스가 다시 시작되었습니다.

몇 년 후 마침내 그들은 따라잡았고 systemd는 이제 열린 파일 설명자를 services 에 연결된 파이프에 저장합니다 systemd-journald. 하지만 이는 다소 우회적인 방식으로 수행됩니다. 즉, 프로세스가 선택한 파일 설명자를 프로세스 #1에 주입하도록 허용합니다. SIGPIPE더 이상 원래의 문제를 은폐할 필요가 없기 때문에 더 이상 표준을 무시할 필요가 없습니다 .

IgnoreSIGPIPE단, 서비스 단위 설정의 기본값은 그대로 유지됩니다 yes.

no서비스 단위 로 변경하세요 .

추가 읽기

관련 정보