서비스의 stdin에 쓰는 방법

Sep 30 2020

CLI가 stdin에 연결된 서비스를 실행 중입니다. 언제를 ssh기계로, 그 서비스의 표준 입력으로 명령을 보낼 수 있도록하고 싶습니다.

systemd.exec 는 그것이 StandardInput=file:/path/to/file일이며 FIFO를 지원 한다고 말합니다 . 가장 간단한 방법 인 것 같습니다.

나는 이것을 내에서 시도했다 ~/.config/systemd/user/foo.service

[Service]
ExecStartPre=mkfifo %t/foo.stdin
ExecStart=cat -
StandardInput=file:%t/foo.stdin
ExecStopPost=rm -f %t/foo.stdin

이 예제에서 다음을 실행하면 저널에 출력이 에코되는 것을 볼 수 있습니다.

echo "hello" > /run/user/1000/foo.stdin

이것에 두 가지 문제가 있습니다.

  1. foo.service: Failed to set up standard input: No such file or directory . StandardInput=이전에 존재해야하는 것 같습니다 ExecStartPre=. 설치하는 동안 고정 된 위치에 영구 파이프를 만들어야합니까 아니면 해결 방법이 있습니까? 수동으로 파일을 만들고 ExecStartPre/ 제거 ExecStopPost하면 작동합니다.
  2. 첫 번째 echo "command"는 잘 처리되지만 전송 EOF및 stdin이 닫힙니다. stdin이 열려 있기를 원했습니다. 대답 ( exec 3> stdin, ..., exec 3>&-)은 bash FD 리디렉션을 사용하는 것 같지만 systemd에서는 사용할 수 없습니다.

답변

3 user3840170 Sep 30 2020 at 09:51

FIFO에 대한 소켓 장치 를 만들 수 있습니다 .

  • foo.socket:

    [Socket]
    ListenFIFO=%t/foo.stdin
    Service=foo.service
    
  • foo.service:

    [Service]
    ExecStart=/bin/cat -
    Sockets=foo.socket
    StandardInput=socket
    StandardOutput=journal
    StandardError=journal
    

다음과 같이 시작하십시오.

systemctl --user start foo.socket

FIFO가 기록되는 즉시 서비스 자체가 시작됩니다. 즉시 시작하려면 대신 다음과 같이 시작하십시오.

systemctl --user start foo.service