Avvia silenziosamente l'attività in background


12

So che puoi usarlo per avviare un processo in background, senza ricevere la notifica quando il processo viene messo in background e quando viene fatto in questo modo:

(comando &) &> / dev / null

Tuttavia, ciò rimuove l'opzione da intercettare al termine del processo ( trap child_done CHLD).

Come posso avere entrambi?

Risposte:


5

task-spooler potrebbe aiutarti.

Come in freshmeat.net :

task spooler è un sistema batch Unix in cui le attività di spool vengono eseguite una dopo l'altra. La quantità di lavori da eseguire contemporaneamente può essere impostata in qualsiasi momento. Ogni utente in ciascun sistema ha la propria coda lavori. Le attività vengono eseguite nel contesto corretto (quello di accodamento) da qualsiasi shell / processo e i suoi output / risultati possono essere facilmente osservati. È molto utile quando sai che i tuoi comandi dipendono da molta RAM, da un sacco di utilizzo del disco, da un sacco di output, o per qualsiasi motivo è meglio non eseguirli tutti contemporaneamente, mentre vuoi mantenere le tue risorse occupate per il massimo beneficio. La sua interfaccia consente di usarlo facilmente negli script.

Task-spooler è disponibile in Debian , Ubuntu e altre distribuzioni.

Ti consente di eseguire una coda di attività e di accedere ai loro output a piacimento.

Per esempio:

$ 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 esegui molti lavori in background, ti sarà sicuramente di aiuto.

Puoi eseguirli in sequenza o in un numero predefinito di slot. È inoltre possibile stabilire dipendenze tra le attività (eseguire task1 solo se task0 è stato completato correttamente).


3

Ecco come farlo in entrambi {ba,z}sh.

Utilizzando una funzione aiuta a non avere bisogno di salvare e ripristinare lo stato di zsh's monitorvariabile mediante l'uso di setopt local_options.

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

Usando questo come segue:

trap 'echo child done' CHLD
silent_background sleep 1

Produrrà il child donemessaggio previsto .


vedi unix.stackexchange.com/q/456549/4778 per una spiegazione, speranzosa.
ctrl-alt-delor,

2

Il reindirizzamento dell'output del comando sembra essere irrilevante perché la notifica viene inviata dalla shell quando un lavoro viene avviato in modo asincrono. Più precisamente, si tratta di una funzione shell (funzionalità) relativa al controllo del lavoro .

Qui, una citazione che viene dal "Manuale di riferimento di Bash", capitolo "Controllo dei lavori", sezione uno.

La shell associa un LAVORO a ciascuna pipeline. Mantiene una tabella dei lavori attualmente in esecuzione, che può essere elencata con il jobscomando. Quando Bash avvia un lavoro in modo asincrono, stampa una riga che assomiglia a:

[1] 25647

che indica che questo lavoro è il numero lavoro 1 e che l'ID processo dell'ultimo processo nella pipeline associato a questo lavoro è 25647. Tutti i processi in una singola pipeline sono membri dello stesso lavoro. Bash utilizza l'astrazione JOB come base per il controllo del lavoro.

Si noti che uno script di shell non visualizza questa notifica.

$ cat test
#!/bin/bash

true & echo true
$ ./test
true

Nei fatti

zsh

La documentazione di Zsh fornisce indicazioni simili su queste notifiche, vedere la man 1 zshmiscsezione "LAVORI". Queste notifiche non vengono visualizzate quando il controllo lavoro è disabilitato.

MONITOR ( -m , ksh: -m )

    Consenti controllo del lavoro. Impostato di default nella shell interattiva.

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

bash

Sembra che Bash visualizzi sempre ad es [1] 25647. La "notifica finale" ad es. [1]+ Done trueNon viene visualizzata quando il controllo lavori è disabilitato.

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

Controllo lavoro disabilitato

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

Conclusione

Non so se disabilitare il controllo dei lavori per nascondere le notifiche sia una buona cosa?

risorse


1

È possibile invocare zshcome shell non interattiva per disabilitare le notifiche di lavoro.

zsh -c '
   trap "echo trapped child_done" CHLD
   sleep 5 &
   #wait
   sleep 10 # simulate other running cmds
   echo script done
'

0

Vedi il seguente esempio:

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

Funziona bene Non c'è bisogno ( ): questo rende una subshell non necessaria. { }stanno solo raggruppando i comandi.


Che stampa [2] 49591e [2] + 49591 exit 1 find /usr, quando non dovrebbe stampare nessuno di questi!
Tyilo,

Siamo spiacenti, ho frainteso la tua domanda così.
Gilles Quenot,

0

Questa è una vecchia domanda, ma una possibile risposta (in bash, non testata con zsh) è usare il controllo del lavoro nella subshell: (command & wait)

Nota: bash sopprime i messaggi di processo in background di inizio / fine nella subshell e non è necessario il reindirizzamento.


Penso che ti sia sfuggita la parte con la trappola. Per quanto ho capito la domanda che il sottoprocesso dovrebbe essere avviato, qualcosa sarà fatto mentre il supprocesso viene eseguito e poi quando il sottoprocesso ha finito qualcos'altro dovrebbe essere eseguito. Con la tua soluzione avvii il sottoprocesso, aspettalo nella subshell e la shell principale attende la subshell. Questo elimina i messaggi, ma non puoi fare qualcosa in parallelo.
Raphael Ahrens,

No, (sleep 5 & wait)ritardi di 5 secondi.
Tom Hale,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.