/ dev / stderr no serviço systemd

4

Estou escrevendo um serviço que deve iniciar a conexão LTE.

Mas o utilitário que estou usando para conectar (sakis3g) está escrevendo para /dev/stderr , que não está disponível no systemd e o log está cheio de

Cannot create /dev/stderr: No such device or address

Existe alguma maneira de contornar isso?

Alterar o script / binário do utilitário infelizmente não é uma opção.

EDIT: Aqui está o serviço:

[Unit]
Description=LTE
After=syslog.target network-online.target
Before=openvpn-client@client
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/mav/LTE/
ExecStartPre=/sbin/ip link set wwan0 down
ExecStart=/opt/mav/LTE/sakis3g connect -g --sudo
ExecStop=/opt/mav/LTE/sakis3g disconnect --sudo

[Install]
WantedBy=multi-user.target

E funciona nesse estado. Mas quando eu começo sakis3g com -g flag para saída de depuração mais detalhada, então os erros stderr aparecem.

    
por Pitel 30.10.2017 / 10:11

1 resposta

4

Se não houvesse stderr, você não veria o erro.

Aqui, o erro é sobre não ser possível abrir o arquivo /dev/stderr , que no Linux é um link simbólico para o arquivo que está aberto no fd 2 (enquanto em outros sistemas, abrir / dev / stderr é como fazer um dup(2) ).

O problema aqui é provável que o fd 2 esteja aberto em um soquete (inet TCP, fluxo Unix ou outro) e você não pode open() um arquivo de soquete.

Se você executar:

sudo lsof -aU +E -d 2

Em um sistema que usa systemd , você notará que o fd 2 da maioria dos serviços é um soquete de fluxo de domínio unix para systemd-journald .

Como solução, você pode começar como:

bash -o pipefail -c '{ /opt/mav/LTE/sakis3g connect -g --sudo 2>&1 >&3 3>&- | cat >&2 3>&-; } 3>&1'

Isso faz stderr um pipe (para cat ) ao invés de um socket, cat encaminhando o que ele recebe no pipe para o stderr original (o socket), e certifica-se que nós preservamos o status de saída do comando com a opção pipefail .

Em qualquer caso, a origem desse sakis3g está disponível e que sakis3g init O arquivo é um script bash que acontece:

echo text >> /dev/stderr

em vez de:

echo test >&2

Até tem alguns > /dev/stderr em vez de >> /dev/stderr , o que é ainda mais errado. Não tem tee -a /dev/stderr | other cmd , o que teria sido um uso legítimo de /dev/stderr e também não funcionaria com stderr em um soquete, então é facilmente corrigível.

Você pode avisá-los sobre o problema levantando um problema no link

    
por 30.10.2017 / 13:26