GNU/Linux >> Linux Esercitazione >  >> Linux

Qualcuno può spiegare in dettaglio cosa fa set -m?

Citando la documentazione di bash (da man bash ):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.

Quindi, detto molto semplicemente, avendo set -m (l'impostazione predefinita per le shell interattive) consente di utilizzare built-in come fg e bg , che verrebbe disabilitato in set +m (l'impostazione predefinita per le shell non interattive).

Tuttavia, non mi è chiaro quale sia la connessione tra il controllo del lavoro e l'interruzione dei processi in background all'uscita, ma posso confermare che ce n'è una:eseguire set -m; (sleep 10 ; touch control-on) & creerà il file se si esce dalla shell subito dopo aver digitato quel comando, ma set +m; (sleep 10 ; touch control-off) & non lo farà.

Penso che la risposta si trovi nel resto della documentazione per set -m :

-m      Monitor  mode. [...]                     Background pro‐
        cesses run in a separate process group and a  line  con‐
        taining  their exit status is printed upon their comple‐
        tion.

Ciò significa che i lavori in background sono iniziati sotto set +m non sono effettivi "processi in background" ("i processi in background sono quelli il cui ID del gruppo di processi è diverso da quello del terminale"):condividono lo stesso ID del gruppo di processi della shell che li ha avviati, piuttosto che avere il proprio gruppo di processi come i processi in background appropriati. Questo spiega il comportamento osservato quando la shell si chiude prima di alcuni dei suoi lavori in background:se ho capito bene, quando si esce, viene inviato un segnale ai processi nello stesso gruppo di processi della shell (quindi uccidendo i lavori in background iniziati sotto set +m ), ma non a quelli di altri gruppi di processi (lasciando così da soli i veri processi in background avviati sotto set -m ).

Quindi, nel tuo caso, il startup.sh lo script presumibilmente avvia un lavoro in background. Quando questo script viene eseguito in modo non interattivo, ad esempio su SSH come nella domanda a cui ti sei collegato, il controllo del lavoro è disabilitato, il lavoro "in background" condivide il gruppo di processi della shell remota e viene quindi terminato non appena la shell esce. Al contrario, abilitando jobcontrol in quella shell, il lavoro in background acquisisce il proprio gruppo di processi e non viene ucciso quando la sua shell madre esce.


L'ho trovato nell'elenco dei problemi di github e penso che questo risponda davvero alla tua domanda.

Non è davvero un problema SSH, è più il comportamento sottile intorno alle modalità non interattive/interattive BASH e alla propagazione del segnale per elaborare i gruppi.

Quanto segue si basa su https://stackoverflow.com/questions/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774 e http:// www.itp.uzh.ch/~dpotter/howto/daemonize, con alcuni presupposti non completamente convalidati, ma i test su come funziona sembrano confermare.

pty/tty =falso

La shell bash lanciata si connette allo stdout/stderr/stdin del processo avviato e viene mantenuta in esecuzione fino a quando non c'è nulla collegato ai socket e i suoi figli sono usciti. Un buon processo demone assicurerà che non aspetti che i suoi figli escano, forchi un processo figlio e poi esca. In questa modalità nessun SIGHUP verrà inviato al processo figlio da SSH. Credo che funzionerà correttamente per la maggior parte degli script che eseguono un processo che gestisce la deamonizzazione stessa e non ha bisogno di essere messo in background. Laddove gli script di init utilizzano "&" per mettere in background un processo, è probabile che il problema principale sarà se il processo in background tenterà mai di leggere da stdin poiché ciò attiverà un SIGHUP se la sessione è stata terminata.

pty/tty =vero*

Se lo script init mette in background il processo avviato, la BASHshell genitore restituirà un codice di uscita alla connessione SSH, che a sua volta cercherà di uscire immediatamente poiché non è in attesa che un processo figlio termini e non è bloccato su stdout/stderr/ stdin. Ciò causerà l'invio di un SIGHUP al gruppo di processi della shell bash genitore, che poiché il controllo del lavoro è disabilitato in modalità non interattiva in bash, includerà i processi figli appena avviati. Laddove un processo daemon avvia esplicitamente una nuova sessione di processo durante il fork o nel processo fork, allora esso o i suoi figli non riceveranno il SIGHUP dall'uscita del processo genitore BASH. Nota che questo è diverso dai lavori sospesi che vedranno un SIGTERM. Sospetto che i problemi attorno a questo solo funzionamento a volte abbiano a che fare con una leggera condizione di gara. Se osservi l'approccio standard alla deamonizzazione -http://www.itp.uzh.ch/~dpotter/howto/daemonize, vedrai che nel codice la nuova sessione è creata dal processo biforcuto che potrebbe non essere eseguito prima del genitore esce, determinando così il comportamento casuale di successo/fallimento menzionato sopra. Un'istruzione sleep concederà tempo sufficiente al processo biforcuto per creare una nuova sessione, motivo per cui funziona in alcuni casi.

pty/tty =true e il controllo del lavoro è esplicitamente abilitato in bash

SSH non si connetterà allo stdout/stderr/stdin della shell bash o ad alcun processo figlio avviato, il che significa che uscirà non appena la shell bash genitore ha iniziato a terminare l'esecuzione dei comandi richiesti. In questo caso, con il controllo del lavoro abilitato in modo esplicito, qualsiasi processo avviato dalla shell bash con '&' per metterli in background verrà immediatamente inserito in una sessione separata e non riceverà il segnale SIGHUP quando il processo padre della sessione BASH termina (connessione SSH in questo caso).

Cosa è necessario correggere

Penso che le soluzioni debbano essere menzionate esplicitamente nella documentazione delle operazioni run/sudo come caso speciale quando si lavora con processi/servizi in background. Fondamentalmente o usa 'pty=false', o dove ciò non è possibile, abilita esplicitamente il controllo del lavoro come primo comando, e il comportamento sarà corretto.

Da https://github.com/fabric/fabric/issues/395


Linux
  1. Cosa succede se "uccidi -9" non funziona?

  2. Cosa fa esattamente Grub_gfxpayload_linux=text?

  3. Quale codice di errore restituisce un processo che restituisce i segfault?

  4. Un processo può avere un proprietario? Cosa significa?

  5. Cosa fa 'set -e' e perché potrebbe essere considerato pericoloso?

Cosa indica questa statistica del processo?

Qual è la tabella dei processi Linux? In cosa consiste?

Cosa fare quando Ctrl + C non può terminare un processo?

Come posso impostare l'affinità del processore di un processo su Linux?

quali processi killer ha Linux?

Cosa fa kill -- -0?