Como fazer a leitura do serviço a partir do soquete FIFO

1

Então, antes de pegar meu machado e destruir meu Desktop, vou tentar perguntar aqui: -)

Eu tenho um serviço ativado por soquete chamado commander.service. Por causa da simplicidade, eu só quero enviar strings ou caracteres para este serviço.

Então eu tenho um arquivo commander.socket:

[Socket]
ListenFIFO=/run/commander.sk

[Install]
WantedBy=sockets.target

Então eu tenho um arquivo commander.service:

[Unit] 
Description=A service reading commands from the given socket

[Service] 
ExecStart=/usr/bin/perl /root/commander.pl
StandardInput=socket
User=root 
Group=root
Restart=no

[Install] 
WantedBy=multi-user.target

Agora, espero que o script que eu executei esteja recebendo essas strings ou caracteres sobre stdin.

O código do script é:

#!/usr/bin/env perl

my $in = *STDIN;
my $out  = *STDOUT;

$out->print("My printing reaches the outside world\n");

while($_ = <$in>) {

    $out->print("Received: ");
    $out->print($_);
    $out->print("\n");


    if($_ == "1") {     
        $out->print("I should run the command associated with 1 ;-) \n");       
    } elsif($_ == "2") {
        $out->print("I should run the command associated with 2 ;-) \n");
    } else {
        $out->print("Oh! did someone just try to trick me?\n");
    }

}

$out->print("And I'm gone!\n");

Como normalmente o stdout deve falar com a revista, também espero que a impressão lá chegue à revista.

Então agora a coisa é:

Quando faço:

echo "1" > /run/commander.sk

O commander.service está sendo ativado, mas no diário só consigo ver o log:

Dez 22 03:18:25 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 03:31:32 phantom systemd[1]: Stopping A service reading commands from the given socket...
Dez 22 03:31:32 phantom systemd[1]: Stopped A service reading commands from the given socket.
Dez 22 03:31:41 phantom systemd[1]: Started A service reading commands from the given socket.

O que significa que a impressão nunca chega ao mundo exterior ... A parada ocorreu manualmente quando atualizei algo e reinstalei a configuração como deveria ser.

Eu sei que quando eu chamo o script command.pl no console, ele funciona como esperado. Lendo as coisas da stin e falando de volta para a stdout.

Eu também sei que algumas horas atrás, quando eu tinha mais equívocos sobre como isso deveria funcionar, a saída impressa chegou realmente ao diário ...

E eu não fiz nada no meu conhecimento que pudesse alterar para onde o stdout iria. A coisa mais importante que fiz nesse meio tempo foi descobrir que eu provavelmente preciso do

StandardInput=socket

linha, para receber o socket como stdin.

Como eu estou lutando com isso agora pelo segundo dia e puxando meus cabelos para fora todo o caminho e começando a me tornar agressivo em direção a minha mobília ^^ Qualquer ajuda seria realmente muito apreciada: -)

De qualquer forma, o código atual está online em: link

UPDATE Ao usar

StandardInput=socket
StandardOutput=journal

O script de serviço é como ativamente rodando para sempre, mas não me dando nenhuma saída no diário.

Comentar as duas linhas resulta em nada ser lido no stdin, mas eu tenho pelo menos stdout no diário. Além disso, o serviço é ativado novamente até que o systemd se recuse a reiniciá-lo.

Aqui está o log @ 04: 05: 58 correndo com essas linhas comentadas. @ 04: 25: 07 correndo com essas linhas

Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4687]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4687]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4689]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4689]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4691]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4691]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4693]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4693]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4695]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4695]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: commander.service: Start request repeated too quickly.
Dez 22 04:05:58 phantom systemd[1]: Failed to start A service reading commands from the given socket.
Dez 22 04:05:58 phantom systemd[1]: commander.service: Unit entered failed state.
Dez 22 04:05:58 phantom systemd[1]: commander.service: Failed with result 'start-limit-hit'.
Dez 22 04:25:07 phantom systemd[1]: Started A service reading commands from the given socket.
    
por Lenny 22.12.2016 / 03:58

1 resposta

3

So I have a commander.socket […]
Then I have a commander.service […]

... e você está escrevendo em Perl.

Perl é o locus do seu problema. Não tem nada a ver com o systemd. Tudo isso com configurações de unidade que você está fazendo é irrelevante, com a exceção de que você deve especificar StandardInput=socket ou gravar seu serviço para usar o descritor de arquivo # 3 .

Seu serviço tem sua entrada padrão conectada ao seu FIFO, e sua saída e erro padrão são conectados a um soquete de fluxo ( /run/systemd/journal/stdout , conversando com o periódico).

Como seus descritores de arquivo de entrada / saída padrão não são dispositivos de terminal, o Perl não é o buffer de linha nem a unidade que armazena em buffer sua E / S; é totalmente em buffer.

Não explicitamente mudar para buffer de unidade ("autoflush") quando a saída padrão não é um dispositivo de terminal, mas é em algum lugar (como um log) onde você deseja ver a saída assim que isso acontece, é um erro muito comum de Perl.

Portanto, ative o buffer da unidade tornando a saída padrão "hot" / "autoflush".

Leitura adicional

por 22.12.2016 / 11:02