Como podemos agendar para executar periodicamente um comando em segundo plano em um determinado shell bash interativo?

0

Um comando pode ser agendado para ser executado periodicamente pelo cron.

Eu queria saber como podemos executar um comando em segundo plano periodicamente em um determinado shell bash interativo?

  • Gostaria de executar o comando a partir de um determinado shell bash interativo, em vez de outros shells em execução, porque preciso do comando para gerar saída com base no estado do shell, por exemplo, saída de jobs no shell fornecido.

  • Eu gostaria de executar o comando em segundo plano, porque gostaria de continuar a executar outros comandos no mesmo shell

  • o comando pode ser um script e, para permitir que o script acesse o estado de um determinado shell, talvez seja necessário source do script no shell.

Por exemplo:

Eu escrevi um exemplo desse script:

$ pwd
/tmp/test
$ cat test.sh 
#! /bin/bash

while true;
do
    dirs -l -p  > /tmp/test/dirs
    jobs > /tmp/test/jobs
    sleep 5
done

e, em seguida, execute-o em um shell bash interativo:

$ source test.sh &

mas os arquivos que obtêm uma saída atualizada do script não contêm a saída de jobs ou dirs -l -p que são executados diretamente no shell fornecido:

$ evince &
$ jobs
[1]-  Running                 source test.sh &
[2]+  Running                 evince &
$ cat /tmp/test/jobs 
$

$ pushd /tmp/
/tmp /tmp/test    
$ dirs -l -p
/tmp/test
/tmp    
$ cat /tmp/test/dirs 
/tmp/test

Eu estava me perguntando por quê? Como podemos realizar a tarefa no início do post?

Obrigado.

    
por Tim 05.05.2018 / 05:00

1 resposta

1

Existem dois problemas:

  1. O script é executado em um subshell não interativo (de forma diferente no shell pai).
  2. O subshell não tem controle de trabalho.

Basta habilitar o controle de trabalho no subshell iniciando o script usando bash -m test.sh & não funcionará, pois isso também significa que ele herdará todos os descritores de arquivo do shell pai. A primeira coisa que acontecerá quando você pressionar Enter é que o script será suspenso.

Em vez disso, vamos interpretar "periodicamente" como "toda vez que eu pressionar Enter para executar um novo comando".

Isso significa que podemos colocar a parte principal do script em PROMPT_COMMAND . Se essa variável tiver um valor, ela será avaliada antes de emitir o próximo prompt.

PROMPT_COMMAND='jobs >/tmp/test/jobs'

Se executarmos sleep 100 & depois disso no prompt e investigar /tmp/test/jobs , veremos que ele contém

[1]+  Running                 sleep 100 &

Após 100 segundos, se nenhuma outra tarefa em segundo plano for iniciada, pressionar Enter atualizará o arquivo para conter

[1]+  Running                 sleep 100 &
[1]+  Done                    sleep 100

Após o próximo Enter , o arquivo estará vazio.

    
por 05.05.2018 / 09:15

Tags