Como suprimir stdout / stderr de uma saída de script de shell?

4

Eu tenho um script que deve parar e recuperar o processo para ser executado em segundo plano:

process_id='ps -eaf | grep -i daemon | grep -v grep | grep -v status | grep -v stop | awk '{print $2}''
(kill -STOP $process_id) &
... # do something else 
(kill -CONT $process_id) &

Isso está funcionando bem, mas no STDOUT / STDERR isso aparece:

[1]  +  8545 Suspended (signal)            /etc/init.d/...

Até agora eu tentei:

(kill -STOP $process_id)
(kill -STOP $process_id) & > /dev/null
/etc/init.d/{name_of_the_daemon} start > /dev/null
(kill -STOP $process_id & ) 2>/dev/null 
(kill -STOP $process_id & disown;) 2>/dev/null 
set +m
(kill -STOP $process_id) & 
(kill -STOP $process_id) & 1>&2

Estas são as etapas que estou fazendo:

  1. crie um arquivo fff em /etc/init.d/
  2. cole o script abaixo
  3. chmod 755 fff
  4. /etc/init.d/fff start

Depois disso, recebo a mensagem "suspenso" ...

De acordo com @sourcejedi meu script não é um daemon; Quando um processo filho do script foi suspenso, a mensagem "suspenso" aparece

Como posso suprimir a saída do shell apenas para essa mensagem em particular?

Aqui está uma versão muito simples do meu script:

#!/bin/bash

pid_script='ps -eaf | grep -i fff | grep -v grep | grep -v status | grep -v stop | awk '{print $2}''

case "$1" in
    start)
    ( sleep 3; kill -STOP $pid_script ) &
    sleep 10;
    (sleep 1; kill -CONT $pid_script) &
    ;;
    stop)
    for p in $pid_script # kill all the other processes related with this script (if any)
        do
            kill -9 $p
        done
esac
    
por toom501 18.09.2018 / 09:26

2 respostas

2

Quando você vê [1] + 7766 Suspended (signal) ... , esta é uma mensagem impressa pelo shell, informando que um de seus processos filhos foi suspenso.

No exemplo fff , há dois processos de shell a serem considerados. Seu shell interativo inicial e o script de shell que é executado como um processo filho.

Seu script organiza a suspensão de si mesmo. A mensagem "Suspenso" é impressa pelo shell interativo. Portanto, esta não é uma opção que você pode ativar ou desativar dentro do script .

Além disso, não há nenhuma opção que você possa definir no shell interativo para ativar ou desativar essa mensagem específica. Não é possível "suprimir" esta mensagem individualmente ... basicamente porque isso nunca é o que você quer fazer: -).

Acho que o script fff não é retomado com sucesso mesmo. Eu acho que pode ser possível modificá-lo para fazer isso. No entanto, retomar a si mesmo é uma ideia terrível. Quando você suspende o script, o shell interativo mostra seu prompt de comando novamente. Ou seja Se você não viu a mensagem "suspenso", parece que seu script terminou. Mas de qualquer forma, se o seu script conseguisse retomar a si mesmo, ele tentaria roubar o controle do terminal do usuário, independentemente do que ele tivesse começado a fazer nesse meio tempo. Isso não é bom!

Acho que você precisa entender, por exemplo que se você iniciou um processo a partir do seu terminal e é um processo filho do seu shell interativo , então não é um processo daemon .

Para iniciar um daemon do seu terminal, o programa deve ser fork () durante a inicialização. O processo original deve sair, e isso permite que o processo continue a ser reexaminado , e. (no unix tradicional) para PID 1 a.k.a. o processo init . E há mais etapas que ele deve incluir também para se desconectar do terminal. Veja por exemplo aqui: Daemonize um processo em shell?

Além disso, se o seu sistema usa systemd , você precisa entender que os scripts herdados de /etc/init.d/ precisam ser iniciados usando systemctl start . Os scripts init.d empacotados no Debian e em outros lugares incluem um hack de compatibilidade que faz isso para você. Mas você deve não usar esse recurso. É uma receita para confusão. O script que você escreveu não tem esse recurso, então você deve usar systemctl start fff .

É altamente recomendável não tentar usar os jogos no script fff em combinação com systemctl start .

Na realidade, systemctl usa uma abordagem diferente para iniciar processos de serviço em segundo plano. Ele envia uma mensagem para o PID 1 (o processo systemd init) e o PID 1 inicia o programa solicitado. Se você definir um serviço systemd nativo, o programa não precisará se daemonizar sozinho. Se você usar um script init.d herdado, o programa ainda precisará ser desmembrado, mas a única coisa que ele conseguirá é informar systemd de que o script init.d terminou de ser iniciado. (Isso torna possível notar algumas falhas de inicialização nos daemons, embora, infelizmente, muitos programas existentes tenham falhas de inicialização que podem acontecer após a etapa de daemonização).

Você não quer se preocupar se e como systemd reagirá ao script init.d parar e retomar a si mesmo.

    
por 19.09.2018 / 14:14
0

Não tenho certeza se entendi seu objetivo corretamente, mas é assim que funciona para mim:

  1. inicie o "daemon", na verdade apenas o processo contínuo de execução: top -d1 >out

  2. no segundo terminal você pode tail -f out se gostar

  3. no terceiro terminal eu corro kill -STOP $(ps -eFH | grep "top -d" |grep -v grep|awk '{print $2}'

Você verá a mensagem 'suspenso' no primeiro terminal de onde o daemon foi iniciado, mas no arquivo out não haverá tais mensagens.

    
por 18.09.2018 / 20:29