GNU/Linux >> Znalost Linux >  >> Linux

Může někdo podrobně vysvětlit, co dělá set -m?

Cituji dokumentaci bash (z 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.

Jednoduše řečeno, mít set -m (výchozí pro interaktivní shelly) umožňuje používat vestavěné moduly, jako je fg a bg , což by bylo zakázáno pod set +m (výchozí nastavení pro neinteraktivní shelly).

Není mi jasné, jaké je spojení mezi řízením úloh a zabíjením procesů na pozadí při ukončení, ale mohu potvrdit, že jedno existuje:spuštění set -m; (sleep 10 ; touch control-on) & vytvoří soubor, pokud člověk opustí shell hned po zadání thatcommand, ale set +m; (sleep 10 ; touch control-off) & nebude.

Myslím, že odpověď leží ve zbytku dokumentace pro 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.

To znamená, že úlohy na pozadí byly spuštěny pod set +m nejsou skutečné "procesy na pozadí" ("Procesy na pozadí jsou ty, jejichž ID skupiny procesů se liší od ID terminálu"):sdílejí stejné ID skupiny procesů jako shell, který je spustil, místo aby měli vlastní skupinu procesů jako správné procesy na pozadí. To vysvětluje chování pozorované, když se shell ukončí před některými ze svých úloh na pozadí:pokud tomu dobře rozumím, při ukončení je odeslán signál procesům ve stejné skupině procesů jako shell (takže zabíjení úloh na pozadí začalo pod set +m ), ale ne k těm z jiných skupin procesů (a tedy ponechávají samotné skutečné procesy na pozadí spuštěné pod set -m ).

Takže ve vašem případě startup.sh skript pravděpodobně spouští úlohu na pozadí. Když je tento skript spuštěn neinteraktivně, například přes SSH jako v otázce, na kterou jste odkazovali, je řízení úlohy zakázáno, úloha „na pozadí“ sdílí skupinu procesů vzdáleného shellu, a je tedy zabita, jakmile se shell opustí. Naopak povolením jobcontrol v tomto shellu získá úloha na pozadí svou vlastní skupinu procesů a není zabita, když se její nadřazený shell ukončí.


Našel jsem to v seznamu problémů github a myslím, že to skutečně odpovídá na vaši otázku.

Ve skutečnosti to není problém SSH, je to spíše jemné chování kolem neinteraktivních/interaktivních režimů BASH a šíření signálu do skupin zpracování.

Následující je založeno na https://stackoverflow.com/questions/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774and http:// www.itp.uzh.ch/~dpotter/howto/daemonize, některé předpoklady nejsou plně ověřeny, ale zdá se, že testy o tom, jak to funguje, potvrzují.

pty/tty =false

Spuštěný bash shell se připojí ke stdout/stderr/stdin spuštěného procesu a je udržován v chodu, dokud není nic připojeno k zásuvkám a jeho děti neukončí. Dobrý démonský proces zajistí, že nebude čekat, až jeho děti opustí, rozvětví podřízený proces a poté skončí. Když je tento režim v tomto režimu, SSH neodešle do dětského procesu žádný SIGHUP. Věřím, že to bude fungovat správně pro většinu skriptů provádějících proces, který si sám poradí s deamonizací a nemusí být na pozadí. Tam, kde init skripty používají '&' na pozadí procesu, pak je pravděpodobné, že hlavním problémem bude, zda se proces na pozadí někdy pokusí číst ze standardního vstupu, protože to spustí SIGHUP, pokud byla relace ukončena.

pty/tty =true*

Pokud je init skript na pozadí spuštěného procesu, nadřazený BASHshell vrátí výstupní kód do SSH připojení, které bude vypadat jako okamžité ukončení, protože nečeká na ukončení podřízeného procesu a není blokováno na stdout/stderr/ stdin. To způsobí odeslání SIGHUP do nadřazené skupiny procesů shellu bash, která, protože je řízení úloh v neinteraktivním režimu v bash zakázáno, bude zahrnovat právě spuštěné podřízené procesy. Pokud proces démona explicitně zahájí novou relaci procesu při rozvětvení nebo v rozvětveném procesu, pak tento nebo jeho potomci neobdrží SIGHUP od ukončení nadřazeného procesu BASH. Všimněte si, že se to liší od pozastavených úloh, u kterých se zobrazí SIGTERM. Mám podezření, že problémy kolem této jediné práce mají někdy co do činění s mírným závodním stavem. Pokud se podíváte na standardní přístup k deamonizaci - http://www.itp.uzh.ch/~dpotter/howto/daemonize, uvidíte, že v kódu je nová relace vytvořena rozvětveným procesem, který nemusí být spuštěn před rodič opustí, což má za následek náhodné úspěšné/neúspěšné chování uvedené výše. Příkaz spánku poskytne dostatek času, aby rozvětvený proces vytvořil novou relaci, což je důvod, proč to v některých případech funguje.

pty/tty =true a řízení úloh je explicitně povoleno v bash

SSH se nepřipojí k stdout/stderr/stdin shellu bash ani žádným spuštěným podřízeným procesům, což bude znamenat, že se ukončí, jakmile nadřazený shell bash spustí provádění požadovaných příkazů. V tomto případě, s explicitně povoleným řízením úloh, všechny procesy spuštěné bash shellem s '&' na pozadí budou okamžitě umístěny do samostatné relace a neobdrží signál SIGHUP, když nadřazený proces relace BASH skončí (v tomto případě připojení SSH).

Co je potřeba opravit

Myslím, že řešení je třeba výslovně uvést v dokumentaci operací therun/sudo jako zvláštní případ při práci s procesy/službami na pozadí. V zásadě buď použijte 'pty=false', nebo tam, kde to není možné, explicitně povolte řízení úlohy jako první příkaz a chování bude správné.

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


Linux
  1. Co když ‚kill -9‘ nefunguje?

  2. Jaký chybový kód vrací proces, který segfaults?

  3. Co dělá `set -x`?

  1. Co dělá „lc_all=c“?

  2. Co dělá zabít -- -0?

  3. Co dělá 'set -e' a proč by mohlo být považováno za nebezpečné?

  1. Co dělá ?

  2. Co dělá „set -f“ v Korn Shell?

  3. Co znamená ve výstupu Ps?