Inicia silenciosamente a tarefa em segundo plano

11

Eu sei que você pode usar isso para iniciar um processo em segundo plano, sem receber a notificação quando o processo é colocado em segundo plano e quando é feito assim:

(command &) &> /dev/null

No entanto, isso remove a opção de interceptação quando o processo é concluído ( trap child_done CHLD ).

Como posso ter os dois?

    
por Tyilo 07.10.2012 / 02:04

6 respostas

5

task-spooler pode ajudá-lo.

Como em freshmeat.net :

task spooler is a Unix batch system where the tasks spooled run one after the other. The amount of jobs to run at once can be set at any time. Each user in each system has his own job queue. The tasks are run in the correct context (that of enqueue) from any shell/process, and its output/results can be easily watched. It is very useful when you know that your commands depend on a lot of RAM, a lot of disk use, give a lot of output, or for whatever reason it's better not to run them all at the same time, while you want to keep your resources busy for maximum benfit. Its interface allows using it easily in scripts.

O spooler de tarefas está disponível em Debian , no Ubuntu e em outras distribuições.

Ele permite que você tenha uma fila de tarefas para executar e acesse suas saídas exatamente como desejar.

Por exemplo:

$ tsp sleep 5
0 
$ tsp sleep 5 
1
$ tsp
ID   State      Output               E-Level  Times(r/u/s)   Command [run=1/1]
2    running    /tmp/ts-out.ZWn6Le                           sleep 5
1    finished   /tmp/ts-out.Fhlcle   0        5.00/0.00/0.01 sleep 5

Se você tiver muitos trabalhos em segundo plano, isso definitivamente ajudará você.

Você pode executá-los sequencialmente ou em uma quantidade predefinida de slots. Você também pode estabelecer dependências entre as tarefas (executar tarefa1 somente se tarefa0 for concluída com êxito).

    
por 02.04.2013 / 23:00
2

O redirecionamento da saída do comando parece ser irrelevante, porque a notificação é enviada pelo shell quando um job é iniciado de forma assíncrona. Mais precisamente, é um recurso de shell (fonctionality) relacionado ao controle de trabalho .

Aqui, uma citação que vem do "Bash Reference Manual", capítulo "Job Control", seção um.

The shell associates a JOB with each pipeline. It keeps a table of currently executing jobs, which may be listed with the jobs command. When Bash starts a job asynchronously, it prints a line that looks like:

[1] 25647

indicating that this job is job number 1 and that the process ID of the last process in the pipeline associated with this job is 25647. All of the processes in a single pipeline are members of the same job. Bash uses the JOB abstraction as the basis for job control.

Observe que um script de shell não exibe essa notificação.

$ cat test
#!/bin/bash

true & echo true
$ ./test
true

Em fatos

Zsh

A documentação do Zsh fornece indicações semelhantes sobre essas notificações, consulte man 1 zshmisc , seção "JOBS". Essas notificações não são exibidas quando controle de trabalho está desativado.

MONITOR (-m, ksh: -m)

    Allow job control. Set by default in interactive shell.

zsh_prompt % setopt no_monitor
zsh_prompt % true & echo true
true
zsh_prompt %
zsh_prompt % 

Bash

Parece que o Bash sempre exibe, por exemplo %código%. A "notificação final", por ex. [1] 25647 não é exibido quando controle de trabalho está desativado.

bash_prompt $ true & echo true
[1] 25647
true
bash_prompt $ 
[1]+  Done                    true

Controle de trabalho desativado

bash_prompt $ set +m       # disable job control
bash_prompt $ true & echo true
[1] 25685
bash_prompt $
bash_prompt $

Conclusão

Eu não sei se desativar controle de trabalho para ocultar as notificações é uma coisa boa?

Recursos

por 29.06.2018 / 21:39
1

Você pode invocar zsh como um shell não interativo para desativar as notificações de tarefas.

zsh -c '
   trap "echo trapped child_done" CHLD
   sleep 5 &
   #wait
   sleep 10 # simulate other running cmds
   echo script done
'
    
por 01.02.2013 / 12:52
1

Veja como fazer isso em {ba,z}sh .

O uso de uma função ajuda a não precisar salvar e restaurar o estado da variável zsh monitor pelo uso de setopt local_options .

# Run the command given by "$@" in the background
silent_background() {
  if [[ -n $ZSH_VERSION ]]; then  # zsh:  https://superuser.com/a/1285272/365890
    setopt local_options no_notify no_monitor
    "$@" &
  elif [[ -n $BASH_VERSION ]]; then  # bash: https://stackoverflow.com/a/27340076/5353461
    { 2>&3 "$@"& } 3>&2 2>/dev/null
  else  # Unknownness - just background it
    "$@" &
  fi
}

Usando isso da seguinte maneira:

trap 'echo child done' CHLD
silent_background sleep 1

Produzirá a mensagem child done esperada.

    
por 29.06.2018 / 08:12
0

Veja o exemplo a seguir:

trap 'echo "DONE"' 0
{ find /usr & } &> /dev/null
wait

Isso funciona bem. Não é necessário ( ) : isso faz com que um subnível não seja necessário. { } estão apenas agrupando comandos.

    
por 07.10.2012 / 02:18
0

Esta é uma pergunta antiga, mas uma resposta possível (no bash, não testada com o zsh) é usar o controle de tarefa no subshell: (command & wait)

Nota: o bash suprime as mensagens do job de fundo de início / fim no subshell e não há necessidade de redirecionamento.

    
por 04.04.2017 / 09:10