Como espero um programa iniciado em outro shell


20

Eu tenho um programa que faz uma grande quantidade de trabalho (leva cerca de 4-5 horas) que é iniciado pelo cron quando todos os dados com os quais trabalha ficam disponíveis. Às vezes, quando estou aguardando o término, gostaria de poder iniciar outro programa (interativo) quando terminar. a chamada em espera parece promissora, mas só aguarda crianças.


O único outro método que eu posso conceber é criar um arquivo a partir do cronjob e, em seguida, usar inotifywait nesse processo. Quando os arquivos forem excluídos, seu segundo processo (executando o inotifywait) poderá ser iniciado.
slm

Eu acho que você poderia fazer algo nesse sentido usando ipctambém a comunicação entre processos. man ipc.
slm

Embora você não esteja assistindo a um serviço para reiniciá-lo, Deus, Monit ou um dos outros pacotes mencionados nesta seção de perguntas e respostas também fariam o trabalho: unix.stackexchange.com/questions/75785/…
slm

O @slm pode ser usado em qualquer sistema de arquivos, por exemplo, aguarde em close_write em / proc / _pid_ / fd / 1?
Hildred

Não tenho certeza, mas isso pode ser outra maneira de fazer isso 8-). Lembro-me de alguns Q onde havia alguma nova funcionalidade do kernel relacionada ao monitoramento de processos semelhante ao inotifywait (para arquivos). Esse novo recurso era para eventos em processo, pensei, mas muitas das perguntas e respostas começam a ocorrer juntas 8-). Eu acho que o A foi fornecido por mim ou por Gilles.
slm

Respostas:


13

Definitivamente, prefiro a solução EDIT # 3 (veja abaixo).

se não no mesmo shell usar um enquanto loop com condição em ps -p retornando true. Coloque um sono no circuito para reduzir o uso do processador.

while ps -p <pid> >/dev/null 2>&1
do
   sleep 10
done 

ou se o seu UNIX estiver suportando / proc (por exemplo, o HP-UX ainda não possui).

while [[ -d /proc/<pid> ]]
do 
    sleep 10
done

Se você quer um tempo limite

timeout=6  # timeout after 1mn  
while ((timeout > 0)) && ps -p <pid> >/dev/null 2>&1
do
   sleep 10
   ((timeout -= 1))
done 

EDIT # 1

Existe uma outra maneira: não use cron . Use o comando batch para empilhar seus trabalhos.

Por exemplo, você pode diariamente empilhar todos os seus trabalhos. O lote pode ser ajustado para permitir algum paralelismo, para que um trabalho bloqueado não pare toda a pilha (depende do sistema operacional).

EDIT # 2

Crie um fifo no seu diretório pessoal:

$ mkfifo ~/tata

no final do seu trabalho:

echo "it's done" > ~/tata

no início do outro trabalho (aquele que está esperando):

cat ~/tata 

Não está pesquisando, é bom IO de bloqueio antigo.

EDIT # 3

Usando sinais:

No início do script, quem está esperando:

echo $$ >>~/WeAreStopped
kill -STOP $$

no final do seu longo trabalho:

if [[ -f ~/WeAreStopped ]] ; then
    xargs kill -CONT < ~/WeAreStopped
    rm ~/WeAreStopped
fi

Polling, eca! Decisão adorável: desperdiçar o tempo do processador ou o meu tempo para ajustar o sono. Tem que haver uma resposta melhor.
Hildred

:) A pesquisa é boa para você, a pesquisa é sem estado, a pesquisa é confiável.
Emmanuel

a sondagem é lenta, a perda de tempo do processador.
Hildred

Com um tempo de execução de 0,01s, os 1440 ps executados durante as 4 horas teriam consumido 14,4s. Muito menos do que o gerenciamento de programador empregos dependências: D
Emmanuel

Eu acho que essa é provavelmente a melhor opção: stackoverflow.com/questions/1058047/… , embora seja hacky.
slm

5

Você pode modificar seu trabalho cron para usar algum sinalizador.

Ao invés de

2  2 * * *           /path/my_binary

Você pode usar

2  2 * * *           touch /tmp/i_m_running; /path/my_binary; rm /tmp/i_m_running

E apenas monitore esse arquivo em script ou mesmo manualmente. Se existir, seu programa está sendo executado; caso contrário, sinta-se livre para fazer o que quiser.

A amostra do script:

while [[ -f /tmp/i_m_running ]] ; do
   sleep 10 ;
done
launch_whatever_you_want

Caso você não goste de usar sleep, você pode modificar o script e executá-lo via cron uma vez a cada X minutos.

Nesse caso, a amostra de script será:

[[ -f /tmp/i_m_running ]] && { echo "Too early" ; exit ; }
launch_whatever_you_want

Dessa forma, é um pouco mais fácil, pois você não precisa encontrar o PID do seu processo cron.


4

Não há facilidade para um processo aguardar a conclusão de outro processo, exceto um pai para aguardar a conclusão de um de seus processos filhos. Se você puder, inicie o programa através de um script:

do_large_amount_of_work
start_interactive_program

Se você não puder fazer isso, por exemplo, antes de começar a grande quantidade de trabalho a partir de um trabalho cron, mas o programa interativo a partir do contexto da sua sessão, faça isso

do_large_amount_of_work
notify_completion

Existem várias maneiras de implementar notify_completion. Alguns ambientes de área de trabalho fornecem um mecanismo de notificação ( abrir uma janela em um monitor X remoto (por que "Não é possível abrir o monitor")? Pode ser útil). Você também pode criar um usando as notificações de alteração de arquivo. No Linux, o recurso de notificação de alteração de arquivo é inotify .

do_large_amount_of_work
echo $? >/path/to/finished.stamp

Para reagir à criação de /path/to/finished.stamp:

inotifywait -e close_write -q /path/to/finished.stamp
start_interactive_program

Se você não pode alterar a maneira como do_large_amount_of_worké chamado, mas sabe qual arquivo ele modifica por último, pode usar o mesmo mecanismo para reagir quando esse arquivo é fechado. Você também pode reagir a outros eventos, como a renomeação de um arquivo (consulte o inotifywaitmanual para obter uma lista de possibilidades).


0

O script sendo acionado pelo cronjob invoca um script de shell vazio no qual você pode inserir tarefas de acompanhamento, se necessário.

É muito semelhante à abordagem de Gilles.

cronjob-task.sh contém:

# do_large_amount_of_work

./post-execute.sh

onde post-execute.shgeralmente está vazio, a menos que você veja que precisa disparar uma tarefa de acompanhamento.

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.