Oct 092010
 

penguinsleepSupponiamo di avere un compito di lunga durata (ad esempio, la compilazione di un programma di grandi dimensioni) che è necessario eseguire, ma anche che vogliate fare altri lavori nello stesso momento. Linux consente di avviare un’attività in background e continuare a fare altre cose dal prompt dei comandi.

Vedremo in questo articolo come mandare i comandi in background, farli poi tornare in foreground, e fare in modo che anche chiudendo la shell corrente o il terminale il processo non resti legato alla sessione ma continui a funzionare.

Una alternativa a questi comandi è utilizzare screen, come visto in un precedente articolo, ma vedremo ora il comando bg ed il carattere speciale &


Compito 1 : far partire un processo direttamente in background

sleep 100 &

Questo farà partire il comando sleep come processo in background, eseguendolo in parallelo agli altri processi presenti nel sistema, il carattere speciale & messo dopo il comando significa questo.

Non c’e’ output a questo comando, e tornete al prompt dei comandi, ma dopo 100 secondi vedrete comparire:
[1]+ Done sleep 100

Compito 2 : Far partire un processo e poi metterlo in background

Questo è molto utile quando lanciate qualche comando che richiederà del tempo e vi accorgete di aver bisogno del prompt dei comandi per dare qualche comando.

sleep 100 ; < CTRL > Z ; bg

In questa sequenza lanciamo un comando (sleep, ma potrebbe essere qualsiasi cosa), dopodiché usiamo  < ctrl > Z per mettere il processo in stato di sospensione (Suspend State) ed infine usiamo bg per far ripartire il processo in background

Esempio di output:

laptop:~$ sleep 100
^Z
[1]+ Stopped sleep 100
laptop:~$ bg
[1]+ sleep 100 &
laptop:~$
[1]+ Done sleep 100

Nota: E’ una buona idea reindirizzare l’output delle attività in background in un file, poiché il processo in background condivide la console con i processi in foreground. Se non lo fate, il processo in background scriverà a schermo qualsiasi output che potrebbe produrre anche mentre si sta modificando un file o digitando un altro comando.

Compito 3 : Spostare un processo da background a foreground

Utile se vogliamo far tornare a schermo un processo messo in background

sleep 100 &; sleep 100; < CTRL > Z ; bg ; jobs ; fg 2

In questa sequenza mettiamo due processi sleep in background, poi utilizziamo il comando jobs per avere una lista di tutti i processi in background ed il comando fg 2 per portare in foreground il secondo processo messo in background

Esempio di output:

laptop:~$ jobs
[1]- Running sleep 100 &
[2]+ Running sleep 100 &

Compito 4 : far partire un processo, scollegarsi e fare in modo che il processo continui

Come esempio semplice, diciamo che avete un comando linux che si chiama myLongRunningJob.sh che volete eseguire, ma sapete che ci metterà 3 ore a terminare e voi volete scollegarvi adesso, come fare ?

nohup myLongRunningJob.sh &

Se lo standard input è un terminale, lo gira su /dev/null. Se lo standard output è un terminale, appende l’output nel file `nohup.out’ se possibile o altrimenti in `$HOME/nohup.out’. Se lo standard error è un terminale, lo gira sullo standard output. Per salvare l’output su un FILE, usate
nohup COMMAND > FILE'

Quindi troveremo l’output del nostro comando nel file nohup.out

Nota: Di per sé, nohup non esegue le attività in background, è necessario dare il carattere & alla fine della riga di comando o usare il CTRL-Z e mettere il processo in background con il comando bg.

Compito 5 : Scollegarsi da un terminale mantenendo attivo un processo fatto partire senza nohup

Dovete scollegarvi da terminale, ma siete a metà di quel lungo task, come fare ?

mylongtask.sh ; < ctrl > Z; bg; disown -h %1

dopo aver messo il processo in background, usiamo disown per perderne la proprietà da terminale. Il disown previene un SIGHUP al processo se il terminale si chiude.

Dalle pagine del manuale: –

disown [-ar] [-h] [jobspec ...]
Without options, each jobspec is removed from the table of active jobs. If the -h option is given, each jobspec is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return value is 0 unless a jobspec does not specify a valid job.

Naturalmente, in ambiente X Windows, tutte queste giravolte innaturali non sono necessarie. Basta aprire un’altra finestra di shell ed eseguire il comando da lì. Puoi guardare i processi in esecuzione in finestre separate, allo stesso tempo, e  non dovete preoccuparvi sull’aggiunta di e commerciali, pipe in uscita a file, o tenere traccia dei processi in foreground rispetto a quelli in background.

Popular Posts:

flattr this!

  12 Responses to “Come mandare comandi in background in Linux”

  1. Oh, never heard about $ disown before, i always use $ screen to keep processes running or run it on startup if it need a terminal like some kind of video players. Thank you.

  2. Use setsid instead of nohup.

  3. @ Lawrence: I’d never heard of setsid before. It looks to be perfect when one doesn’t care about STDIN/STDOUT, but needs to launch something from a script that should then terminate without affecting the launched program (as is often the case when launching an X based program).

    @ Linuxaria: After using &; disown for some time, I had been experimenting with nohup, but was having problems with it. Your comment that the & is still needed prompted me to discover why. (I had been using it, but after the redirect and apparently I needed it before the redirect.)

    Between the two tips, one in the OP one in the comments, this has just solved a serious frustration I’ve been working to solve on and off for months! =:^)

  4. Also the “at” command is an alternative to run things on the background.

  5. disown! nice tip, been wondering about that

    (very good for e.g. when you’ve started a huge sort without nohup/screen, and then find you have to log off from your ssh session)

  6. O attivato un processo con comando: mylongtask.sh ; Z; bg; disown -h %1 e funziona

    Una volta aperto il terminal come puoi fermare processo che lavora in background

    • Ciao Cristian,

      cerca il numero di pid del processo con:
      ps -ef |grep mylongtask

      Poi “uccidi” il processo con kill -9 NUMERO, questo interromperà il processo subito.

      • e invece per riportarlo in primo piano (il comando fg non mi funziona, e il comando jobs dà nessun risultato)

        • Ciao,

          Se hai usato nohup o equivalente, non riesci più (che io sappia) a riportarlo in foreground, per questi casi forse ti è più utile uno screen ?

  7. A me non funziona… se esco da terminale mi killa il processo….

    • Ciao, per uscire dal terminale e mantenere il processo attivo devi utilizzare nohup o disown (se il processo è già partito) cosa è che non ti funziona ?

      Io ho appena provato ad aprire un terminale e dare:

      mint-desktop ~ $ xterm
      ^Z
      [1]+ Stopped xterm
      mint-desktop ~ $
      mint-desktop ~ $
      mint-desktop ~ $ disown %1
      bash: warning: deleting stopped job 1 with process group 3232

      A questo punto chiudo il terminale e xterm mi rimane aperto.

 Leave a Reply

(required)

(required)


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>