Como posso desanexar um processo de um script bash?


18

Estou tentando desanexar um processo de um script bash para que o SIGINT não seja encaminhado para o processo quando eu sair do script.

Eu usei o disowncomando diretamente no terminal, no entanto, no bash, disownnão impede que o SIGINT seja encaminhado. O objetivo deste script é iniciar o openocd e depois o gdb com uma única chamada. Como o script nunca sai (está executando o gdb), o SIGINT ainda é encaminhado do gdb para o openocd, o que é um problema, pois o SIGINT é usado como o comando de parada no gdb.

No terminal, seria algo parecido com isto:

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

quando invocado no terminal nesta ordem, o SIGINT não é passado do gdb para o openocd. No entanto, se essa mesma chamada estiver em um script bash, o SIGINT será passado.

Qualquer ajuda seria muito apreciada.

ps esse problema está no OS X, mas estou tentando usar ferramentas que também são portáveis ​​para todas as ferramentas do Unix.


nohupnão é a resposta certa. Você deve adicionar algum código de exemplo ou pseudocódigo para mostrar com mais precisão o que deseja.
precisa

11
Você está aberto a usar uma ferramenta como screen?
22816 Eric Renouf

Respostas:


17

Para desanexar um processo de um script bash:

nohup ./process &

Se você interromper o script bash com SIGINT(ctrl + c) ou o shell sair do envio, SIGHUPpor exemplo, o processo não será incomodado e continuará sendo executado normalmente. stdout& stderrSerá redirecionado para um arquivo de log: nohup.out.

Se você deseja executar um comando desanexado enquanto pode ver a saída no terminal, use tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

Por que é nohupnecessário? Qual é a diferença entre nohup COMMAND &e COMMAND &se seu objetivo é apenas executar o comando em segundo plano e liberar o terminal?
James Wierzba

@JamesWierzba Uma das diferenças é que, se você precisar que o comando continue em execução mesmo depois de sair do shell, o nohup é o caminho a seguir. Existem milhares de explicações extensas na web. Por exemplo stackoverflow.com/questions/15595374/…
marc


4

A solução que encontrei envolve um programa chamado 'desanexar', escrito por Annon Inglorion e disponível para download em seu site

Uma vez compilado, ele pode ser usado em um script da seguinte maneira:

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

Essa primeira linha cria um novo processo (executando o openocd) e armazena a identificação do processo no arquivo (debug.pid) para uso posterior. Isso evita os problemas de grepping para o pid, conforme fornecido na resposta de Oliver. Ao sair do próximo programa de bloqueio (gdb), o arquivo que armazena o pid é usado para matar o processo desanexado diretamente.


Pode confirmar, detachfaz maravilhas.
AS

2

uma solução simples e portátil:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

Algumas advertências de portabilidade: as psopções dependem do sistema operacional! você poderia passar a usar uma variante: { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. atnão pôde estar disponível (estranho, mas isso acontece ...). $(...)precisa de um shell não muito antigo; caso contrário, use reticulares.


Isso parece perigoso, o grepping for pid pode fazer coisas inesperadas se mais de um processo estiver sendo executado com o mesmo nome, ou mesmo, se outro processo contiver a palavra openocd.
orion

11
@ orion: eu dou um exemplo simples para dar as idéias, essas preocupações que você menciona são fáceis de se livrar: atinicie um script que inicie o programa e forneça seu pid em um arquivo, e faça com que o script principal espere por isso arquivo para aparecer e, em seguida, leia o pid dele.
Olivier Dulac 15/03

é claro que você deve substituir no meu exemplo (excessivamente simples) o grep por um teste dentro do awk, na coluna da direita (us $ 8, geralmente) (as colunas dependem do seu sistema operacional e da versão / opções do ps)
Olivier Dulac
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.