Pergunta

Como você pode suprimir o Terminated Mensagem que surge depois que você mata um processo em um script bash?

tentei set +bm, mas isso não funciona.

Eu sei que outra solução envolve ligar exec 2> /dev/null, mas isso é confiável?Como faço para redefini-lo para poder continuar a ver o stderr?

Foi útil?

Solução

A resposta curta é que você não pode. Bash sempre imprime o status das tarefas de primeiro plano. A bandeira monitoramento se aplica somente para trabalhos de fundo, e apenas para os reservatórios interativos, não scripts.

ver notify_of_job_status () in jobs.c.

Erro Como você disse, você pode redirecionar tão padrão está apontando para / dev / null, mas então você perca quaisquer outras mensagens de erro. Você pode torná-lo temporária, fazendo o redirecionamento em um subshell que executa o script. Isso deixa o ambiente original sozinho.

(script 2> /dev/null)

que vai perder todas as mensagens de erro, mas apenas a partir desse roteiro, e não de qualquer outra coisa correr naquele shell.

Você pode salvar e restaurar erro padrão, redirecionando uma nova FileDescriptor a ponto de lá:

exec 3>&2          # 3 is now a copy of 2
exec 2> /dev/null  # 2 now points to /dev/null
script             # run script with redirected stderr
exec 2>&3          # restore stderr to saved
exec 3>&-          # close saved version

Mas eu não recomendo isso - a única vantagem do primeiro é que ele salva uma invocação de sub-shell, ao ser mais complicada e, possivelmente, até mesmo alterar o comportamento do script, se os descritores de arquivo altera de script .


EDIT:

Como resposta cheque resposta mais adequada, dada por Mark Edgar

Outras dicas

A fim de silenciar a mensagem, você deve estar redirecionando stderr no momento a mensagem é gerada . Porque o href="http://ss64.com/bash/kill.html" rel="noreferrer"> kill comando envia um sinal e não esperar que o processo de destino para responder, redirecionando stderr do comando kill faz você não é bom. A festa builtin wait foi feito especificamente para esta finalidade.

Aqui está um exemplo muito simples que mata o comando mais recente fundo. ( Saiba mais cerca de US $! Aqui. )

kill $!
wait $! 2>/dev/null

Porque ambos kill e wait aceitar vários pids, você também pode fazer kills lote. Aqui está um exemplo que mata todos os processos em segundo plano (do atual processo / script é claro).

kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null

Eu estava trouxe até aqui de : matar silenciosamente processo função fundo .

Inspirado por Março resposta . Eu estava usando kill -INT como ele sugere, com algum sucesso, mas percebi que não estava matando alguns processos. Depois de testar alguns outros sinais vejo que SIGPIPE vai matar bem sem uma mensagem.

kill -PIPE

ou simplesmente

kill -13

Solução: utilização SIGINT (só funciona em conchas não-interativas)

Demonstração:

cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF

sh silent.sh

http://thread.gmane.org/gmane.comp. shells.bash.bugs / 15798

Talvez separar o processo do processo de shell atual chamando disown?

É isso que todos nós estamos procurando?

Não queria:

$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+  Done                    sleep 3
$

Procura-se:

$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$

Como você pode ver, nenhuma mensagem de fim do trabalho. Obras para me em bash scripts, bem como, também para processos em segundo plano mortos.

control 'set + M' desativa trabalho (ver 'set help') para o shell atual. Então, se você digitar o comando em uma subshell (como feito aqui entre parênteses) você não vai influenciar as configurações do shell atual de controle de trabalho. A única desvantagem é que você precisa para obter o PID do seu processo de fundo de volta para o shell atual, se você quiser verificar se ele terminou, ou avaliar o código de retorno.

Outra forma de notificações de trabalho desativar é colocar o seu comando para ser em segundo plano em uma construção sh -c 'cmd &'.

#!/bin/bash
# ...
pid="`sh -c 'sleep 30 & echo ${!}' | head -1`"
kill "$pid"
# ...

# or put several cmds in sh -c '...' construct
sh -c '
sleep 30 &
pid="${!}"
sleep 5 
kill "${pid}"
'

Isso também funciona para killall (para aqueles que preferem-lo):

killall -s SIGINT (yourprogram) 

suprime a mensagem ... Eu estava correndo mpg123 no modo de fundo. Ele só poderia silenciosamente ser morto, enviando um ctrl-c (SIGINT) em vez de um SIGTERM (padrão).

disown fez exatamente a coisa certa para mim - o exec 3> & 2 é arriscado para uma série de razões - set + bm não parecem trabalhar dentro de um script, apenas no prompt de comando

sucesso teve com a adição de 'jobs 2>&1 >/dev/null' para o script, não é certo se ele vai ajudar ninguém do script, mas aqui está um exemplo.

    while true; do echo $RANDOM; done | while read line
    do
    echo Random is $line the last jobid is $(jobs -lp)
    jobs 2>&1 >/dev/null
    sleep 3
    done

Eu achei que colocar o comando kill numa função e depois backgrounding a função suprime a saída de terminação

function killCmd() {
    kill $1
}

killCmd $somePID &

Simples:

{ kill $! } 2>/dev/null

Advantage? pode usar qualquer sinal

ex:

{ kill -9 $PID } 2>/dev/null
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top