A maneira “correta” de testar se um serviço está sendo executado em um script

51

Meu problema:

Estou escrevendo um script e gostaria de verificar se um determinado serviço está sendo executado.

Eu sei como fazer isso manualmente, com $ service [service_name] status .

Mas (especialmente desde a mudança para o systemd) que imprime um monte de texto que é um pouco confuso para analisar. Eu assumi que há um comando feito para scripts com saída simples ou um valor de retorno que posso verificar.

Mas pesquisar no Google produz apenas uma tonelada de resultados "Oh, apenas ps aux | grep -v grep | grep [service_name] ". Essa não pode ser a melhor prática, é? E se outra instância desse comando estiver em execução, mas não iniciada pelo script de inicialização do SysV?

Ou eu deveria calar a boca e sujar as mãos com um pouco de pgrep?

    
por Nick S 07.10.2017 / 08:53

4 respostas

74

systemctl tem um is-active subcomando para isso:

systemctl is-active --quiet service

sairá com status zero se service estiver ativo, diferente de zero, tornando-o ideal para scripts:

systemctl is-active --quiet service && echo Service is running

Se você omitir --quiet , também emitirá o status atual para sua saída padrão.

Como apontado por don_crissti , algumas unidades podem estar ativas, embora nada esteja sendo executado para fornecer service: unidades marcadas como “RemainAfterExit” são consideradas ativas se saem com sucesso, a idéia é que elas fornecem um serviço que não precisa de um daemon ( eg eles configuram algum aspecto do sistema). Unidades envolvendo daemons, no entanto, só estarão ativas se o daemon ainda estiver em execução.

    
por 07.10.2017 / 09:52
18

systemctl tem um modo adequado para script; use show em vez de status e adicione as opções -p / --properties e --value para obter apenas a saída desejada.

Aqui está um exemplo (de um sistema Ubuntu 17.04):

$ systemctl show -p SubState --value NetworkManager
running

A execução (ou não) é um SubState . Se você quiser saber se um serviço está ativo, use a propriedade ActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

Notas do man :

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".
    
por 07.10.2017 / 09:15
8

Como complemento à resposta de Zanna, a opção --value para systemctl show foi introduzida com a versão 230 do systemd . Por isso, pode não estar disponível em certas distros como debian jessie.

Nesse caso, pode-se emular a opção usando sed:

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running
    
por 03.04.2018 / 17:59
2

Em vez de usar o comando sed como na resposta do Oxmel, basta usar cut -d'=' -f 2 para todos os tipos de propriedades consultadas:

por exemplo:

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running
    
por 08.08.2018 / 14:08