Descobri systemd-run
que permite executar processos em segundo plano uma vez ("serviços transitórios"). Eu sempre especifico o nome da unidade de serviço com --unit $NAME
. Mas se eu já executei o systemd-run
comando e meu processo estiver em execução, systemd-run
ele falhará, com código de saída diferente de zero. Existe alguma maneira de dizer systemd-run
para ser mais idempotente e não falhar neste caso?
Atualmente estou fazendo:
systemctl is-active $NAME || systemd-run --unit $NAME $COMMAND
Existe uma maneira melhor?
Isso está no Ubuntu 18.04, com o systemd atual para isso (versão 237?)
-G, --coletar
Descarregue a unidade transitória depois de concluída, mesmo que tenha falhado. Normalmente, sem essa opção, todas as unidades que foram executadas e falharam são mantidas na memória até que o usuário redefina explicitamente seu estado de falha com systemctl reset-failed ou um comando equivalente. Por outro lado, as unidades que funcionaram com sucesso são descarregadas imediatamente. Se esta opção estiver ativada, a "coleta de lixo" das unidades é mais agressiva e descarrega as unidades, independentemente de terem saído com sucesso ou falhado. Esta opção é um atalho para --property=CollectMode=inactive-or-failed, veja a explicação para CollectMode= em systemd.unit(5) para mais informações.
Eu não acho que há uma maneira de não falhar.
O problema aqui é que os nomes das unidades do systemd devem ser exclusivos. Se não forem, manipular as unidades pode se tornar ambíguo. Por esse motivo, o systemd percebe um erro se você tentar duplicar os nomes das unidades, e não acho que haja uma maneira de fazê-lo pensar o contrário.
Se você pudesse convencer
systemd-run
a executar o segundo serviço com o mesmo nome, o que aconteceria se você emitisse umsystemctl stop
comando? Qual das duas unidades com nomes idênticos deve parar? Aquele que você correu primeiro? O último? Ambos?Você precisará
--collect
excluir a unidade (consulte a resposta https://serverfault.com/a/1056478/161855 ).Isso introduz um leve TOCTOU , mas é melhor do que nada e não causará
systemd-run
a impressão de um erro se a unidade já estiver em execução.