Diferença entre o systemd e o programa de partida do terminal

4

Estou curioso para saber qual é essa diferença entre os programas que são; iniciado com o systemd quando habilitado através do systemctl, contra aqueles iniciados por meio do /etc/rc.local ou através do CLI.

Por exemplo, eu estava recentemente usando o shairport-sync para o raspberry pi. Inicialmente, eu configurei o shairport-sync para iniciar por meio do sudo systemctl ativado shairport-sync.

Mais adiante, usei uma funcionalidade em shairport-sync para executar scripts antes e depois para dispositivos que se conectam.

Para minha surpresa, os scripts, quando executados por shairport-sync , não fizeram kill arecord ou aplay

No entanto, quando eu executar o script via terminal, o script será executado e eliminado arecord e aplay .

Para me confundir ainda mais, eu matei shairport-sync e comecei via terminal para ver a saída do que estava acontecendo. Quando fiz isso, os scripts funcionavam como eu esperava quando o dispositivo conectou e matou arecord e aplay . Então, como uma correção, desativei shairport-sync em sysmtectl e configurei para executar em /etc/rc.local como uma solução rápida. Depois de um reboot funcionou como eu esperava.

Isso me leva a acreditar que há alguma diferença entre um programa executado como parte de systemd e um programa que é executado quando iniciado via /etc/rc.local ou o CLI.

Por que isso acontece? Isso é devido a diferentes níveis de execução? Alguma magia negra?

O script executado quando um dispositivo se conecta a shairport-sync é o seguinte: shairportstart.sh

#!/bin/sh
/usr/bin/sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
        /usr/bin/amixer set Speaker 40%
else
        /usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&

exit 0

Aqui está o script de desvanecimento: shairportfade.sh

#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do  
    /usr/bin/amixer set Speaker 1+
done
exit 0

O script executado quando um dispositivo se desconecta em shairport-sync é o seguinte: shairportend.sh

#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0

Encontrei o seguinte erro no /var/log/syslog somente quando o shairport-sync foi executado inicialmente como parte de systemd . Quando shairport-sync foi executado a partir da CLI ou /etc/rc.local , não houve erros presentes.

Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified

Por favor, note que a única diferença é como shairport-sync é inicialmente iniciado, quando os dispositivos se conectam ou desconectam shairport-sync continua a ser executado.

    
por Brett Reinhard 23.01.2017 / 22:11

1 resposta

7

Variações de "Por que as coisas se comportam de maneira diferente em systemd?" são uma pergunta frequente.

Sempre que alguma coisa é executada no CLI e não no systemd, existem algumas categorias amplas de possibilidades para explicar as diferenças.

  1. Diferentes variáveis de ambiente . systemd documenta as variáveis de ambiente que ele passa em man systemd.exec na seção Variáveis de ambiente em processos gerados . Se você quiser inspecionar a diferença você mesmo, você pode usar systemd-run /path/to/binary , ele executará seu aplicativo em um escopo transitório, pois ele seria executado por um serviço systemd. Você receberá uma saída como: Running as unit: run-u160.service . Você pode então journalctl -u run-u160.service revisar a saída. Modifique seu aplicativo para descarregar as variáveis de ambiente que ele recebe e compare a execução da CLI com a execução do systemd. Se o aplicativo não for convenientemente modificado, você pode usar apenas systemd-run env para ver as variáveis de ambiente que seriam passadas e revisar o registro de diário resultante para ele. Se você está tentando iniciar um aplicativo GUI X11, a variável de ambiente DISPLAY precisa ser definida . Nesse caso, considere usar o recurso de "início automático" do ambiente de área de trabalho em vez de systemd .
  2. Restrições de recursos . Consulte man systemd.resource-control para valores de configuração que podem restringir o consumo de recursos. Use systemctl show your-unit-unit.service para verificar os valores de configuração completos que afetam o serviço que você está tentando iniciar.
  3. Shell não interativo . Seu ambiente bash CLI é um shell de login interativo . Ele originou arquivos como .bashrc que systemd não. Além de definir variáveis de ambiente, esses scripts podem fazer várias outras coisas, como conectar um agente SSH para que as ações SSH não exijam um login. Veja também Diferença entre o Login Shell e o Non-Login Shell?
  4. Não TTY . Sua sessão interativa está conectada a um TTY que alguns programas como sudo e ssh esperam ao solicitar senhas. Veja também sudo: no tty presente e nenhum programa askpass especificado
  5. Relativo vs. Caminhos Absolutos . Trabalho binário relativo no shell, mas conforme documentado em man systemd.service , o primeiro argumento para ExecStart= deve ser um caminho absoluto para um binário.
  6. Sintaxe de linha de comando restrita . As CLIs do shell suportam muitos metacaracteres, enquanto o systemd tem uma sintaxe de linha de comando muito restrita . Dependendo de suas necessidades, você poderá replicar a sintaxe do Shell com systemd executando explicitamente seu comando por meio de um shell: ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'

É um recurso que o sistema executa seu código em um ambiente consistente com controles de recursos. Isso ajuda com resultados reproduzíveis e estáveis a longo prazo, sem sobrecarregar o hardware.

    
por 23.01.2017 / 22:54