Bash Achtergrondprocesbeheer

  • Giles Benson
  • 0
  • 3013
  • 795
>

Het komt vaak voor dat een Bash-ontwikkelaar of -gebruiker een proces op de achtergrond wil uitvoeren, hetzij vanaf de opdrachtregel of vanuit een bash-script, en datzelfde proces later opnieuw wil afhandelen. Er zijn verschillende opdrachtregelprogramma's waarmee u dit kunt doen. Het kunnen starten, beheren en vernietigen van achtergrondprocessen is een vereiste voor veel meer geavanceerde niveautaken, vooral op het gebied van geavanceerde scripting en procesbeheersing.

In deze tutorial leer je:

  • Hoe achtergrondprocessen te starten, af te handelen en / of te beheren en te vernietigen
  • Welke opdrachtregelprogramma's zijn beschikbaar om u te helpen bij het beheer van Bash-processen
  • Voorbeelden die het gebruik van achtergrondprocessen benadrukken op de Bash-opdrachtregel
Bash Achtergrondprocesbeheer

Gebruikte softwarevereisten en -conventies

Softwarevereisten en Linux Command Line-conventies
Categorie Vereisten, conventies of gebruikte softwareversie
Systeem Linux-distributie-onafhankelijk
Software Bash-opdrachtregel, op Linux gebaseerd systeem
Andere Elk hulpprogramma dat niet standaard in de Bash-shell is opgenomen, kan worden geïnstalleerd met sudo apt-get install utility-name (of yum installeren voor op RedHat gebaseerde systemen)
Conventies # - vereist dat linux-commando's worden uitgevoerd met root-privileges, hetzij direct als rootgebruiker, hetzij door gebruik van sudo opdracht
$ - vereist dat linux-commando's worden uitgevoerd als een gewone niet-geprivilegieerde gebruiker

Voorbeeld 1: een proces op de achtergrond starten en terug naar de voorgrond brengen

$ slaap 1000 & [1] 25867 $ fg slaap 1000 

Hier begonnen we een slaapproces van 1000 seconden op de achtergrond. Als we een proces op de achtergrond willen plaatsen, kunnen we het ampersand (&) teken achter een commando. Hierdoor wordt het proces op de achtergrond geplaatst en wordt het PID (Proces-ID, een identificatienummer dat elk proces identificeert dat op een Linux-machine wordt uitgevoerd). In dit voorbeeld is de PID is 25867. Merk op dat het proces blijft draaien wanneer het op de achtergrond wordt geplaatst, wat ons het beste van twee werelden geeft; het proces wordt uitgevoerd en in de tussentijd krijgen we onze opdrachtregel terug! Super goed.

Vervolgens plaatsen we het proces weer op de voorgrond (alsof er nooit een achtergrondinstructie is geweest) door de fg (d.w.z. voorgrond) commando. Het resultaat is dat we zien welk proces weer op de voorgrond komt te staan ​​(d.w.z.. slaap 1000) en onze opdrachtprompt keert niet terug omdat we de slaap terug op de voorgrond hebben geplaatst en de opdrachtprompt keert alleen terug als de 1000 seconden slaap is voltooid.

Laten we zeggen dat we de slaap 1000 op de achtergrond, deed 500 seconden ander werk en werd vervolgens uitgevoerd fg... Hoe lang zou de slaap nog duren? Als je 500 seconden raadt (of wist), dan heb je gelijk. De eerste 500 seconden werden als achtergrondproces uitgevoerd en de tweede 500 als voorgrondproces.

Merk ook op dat als je de shell beëindigt, je commando zal eindigen - of het nu op de achtergrond draait, of op de voorgrond (tenzij je het verstoot, meer hierover in het volgende voorbeeld).

Voorbeeld 2: een proces afwijzen

$ sleep 1000 & [1] 26090 $ disown% 1 $ 

Hier begonnen we nog eens 1000 seconden te slapen, en we werden geïnformeerd over de PID van het achtergrondproces zoals eerder. Vervolgens hebben we geëxecuteerd % 1 afwijzen, verwijzend naar het eerste achtergrondproces (zoals ook aangegeven door de [1] voor de PID!), en Bash opdragen om dit proces van de huidige shell te disassociëren (loskoppelen). Het is niet zo dat het wordt losgekoppeld van de huidige gebruiker (en bijvoorbeeld ps -ef | grep slaap | grep -v grep zal inderdaad nog steeds uw gebruikersID tonen), maar eerder vanuit de huidige shell-sessie. Kijken:

$ sleep 1000 & [1] 26214 $ disown% 1 $ ps -ef | grep slaap | grep -v grep roel 26214 26120 0 13:13 pts / 3 00:00:00 slaap 1000 $ exit 

Open vervolgens een nieuwe shell en voer het ps we kunnen zien dat het commando er nog steeds is en nu is gekoppeld aan PPID (Parent PID) 1 in plaats van 26120 als ouder-PID:

$ ps -ef | grep slaap | grep -v grep roel 26214 1 0 19:48? 00:00:00 slaap 1000 

Het is alsof de shell nog steeds draait (let op het 26214 PID is nog steeds actief / geassocieerd met het hardlopen slaap), maar het actieve commandoregelgedeelte is verdwenen!

Geweldig, dus dit geeft ons een manier om processen los te koppelen van de huidige shell en er zo voor te zorgen dat ze blijven draaien wanneer onze shell-sessie wordt gesloten.

Voorbeeld 3: een commando op de achtergrond plaatsen

$ slaap 1000 ^ Z [1] + Gestopte slaap 1000 $ bg% 1 [1] + slaap 1000 & $ 

Hier zijn we begonnen met een slaap 1000 op de voorgrond (nr & werd gebruikt), en het onderbroken dat proces met de sneltoets CTRL + z. Merk op dat terwijl de output zegt ^ Z (en ^ is een symbool om aan te geven CTRL), de Z is eigenlijk een kleine letter z, dus je hoeft niet te gebruiken VERSCHUIVING, alleen maar CTRL + z.

Merk op dat het proces feitelijk is gestopt, het is niet verder gegaan. Nu hebben we het proces op de achtergrond geplaatst en gepauzeerd. Om dit proces nu te laten doorgaan, hebben we twee opties; fg% 1 - d.w.z. plaats het proces aangegeven door [1] terug naar de voorgrond en normaal blijven rennen, of bg% 1 die het proces zal hervatten, maar op de achtergrond. In het voorbeeld kunnen we de laatste zien, en onze opdrachtprompt keert terug zoals verwacht.

Merk op dat het bovenstaande enigszins kan worden aangevuld met verloochenen, overeenkomend met een vaak gebruikte manier om een ​​proces af te handelen bij gebruik van een externe server. Stel dat u via SSH bent verbonden met een externe server en een grote taak bent begonnen, bijvoorbeeld een back-up of het genereren van rapporten. Nu wilt u uw kantoor voor een dag verlaten, maar weet u niet zeker of uw SSH-verbinding de hele nacht actief zal blijven, en zelfs of uw computer niet in slaapstand zal gaan of iets dergelijks. Elk van deze acties kan de lopende taak in gevaar brengen!

Dan kunt u het volgende doen;

$ sleep 1000 ^ Z [1] + Gestopte slaap 1000 $ bg% 1 [1] + slaap 1000 & $ disown% 1 $ 


En loop met plezier en veilig weg van uw computer (nadat u hem hebt vergrendeld;), want u kunt er zeker van zijn dat - zelfs als uw SSH-verbinding uitvalt, of uw computer in winterslaap gaat, of de schoonmaakster het netsnoer uitschakelt - dat uw baan zal blijven rennen. Omdat het proces niet meer in bezit is van / losgekoppeld is van de huidige shell-sessie, zal het blijven draaien, zelfs als de huidige shell-sessie op de een of andere manier wordt beëindigd.

Een klein voorbehoud is dat u niet kunt gebruiken fg 's ochtends om de taak weer op de voorgrond te krijgen, zelfs als je SSH-verbinding en shell nooit zijn beëindigd / mislukt:

$ fg bash: fg: huidig: zo'n job niet $ fg% 1 bash: fg:% 1: zo'n job niet 

Als het verstoten is, is het losgekoppeld en verdwenen! De taak zal echter nog steeds op de achtergrond worden uitgevoerd en je kunt hem zelfs doden met behulp van zijn PID (zoals kan worden waargenomen in ps -ef | grep uw_procesnaam | grep -v grep.

Voorbeeld 4: Meerdere achtergrondprocessen en beëindigingsprocessen

Eerst starten we twee processen op de achtergrond met behulp van onze vertrouwde slaap 1000 voorbeeld:

$ slaap 1000 & [1] 27158 $ slaap 1000 & [2] 27159 

We kunnen hier zien dat twee achtergrondprocessen ([1] en [2], met PID's 27158 en 27159 respectievelijk) werden gestart. Vervolgens doden we het eerste proces:

$ kill% 1 $ [1] - Slaap beëindigd 1000 $ 

Dat was duidelijk / gemakkelijk, toch? Een vraag die men zich kan stellen is waarom de Terminated-informatie niet onmiddellijk wordt weergegeven (een extra enter-toets is vereist zoals u kunt zien) en de reden is dat het proces niet werd beëindigd voordat de opdrachtregel werd teruggestuurd. Als onderdeel van het werk dat elke keer wordt gedaan voordat een nieuwe opdrachtregel wordt weergegeven, is het rapporteren van een aantal statussen, inclusief de achtergrondprocesstatus indien nodig. Dus wanneer enter opnieuw werd ingedrukt (aangegeven door het lege $ regel wordt een rapport van het beëindigde proces weergegeven.

Voorbeeld 5: het ene gedaan voor het andere

Laten we opnieuw twee processen starten, maar deze keer slaapt het tweede proces slechts 3 seconden:

$ slaap 1000 & [1] 27406 $ slaap 3 & [2] 27407 $ 

Na ongeveer 5 seconden op enter te drukken, zien we:

$ [2] + Klaar met slapen 3 

Wat gebeurt er nu als we gebruiken fg in dit geval zonder het origineel [1] specificeerder?

$ fg sleep 1000 ^ Z [1] + Gestopte slaap 1000 $ 


Het eerste proces gaat door! Dit is ook het geval als de omgekeerde procedure is gebruikt:

$ sleep 10 & [1] 27346 $ sleep 1000 & [2] 27347 $ [1] - Klaar met slapen 10 $ fg slaap 1000 ^ Z [2] + Gestopte slaap 1000 

De fg commando neemt altijd het laatste commando dat op de achtergrond werd geplaatst (en dat nog niet voltooid was), en plaatst het weer op de voorgrond.

Gevolgtrekking

In dit artikel hebben we verschillende opdrachten bekeken, waaronder bg, fg en de achtergrond Bash idioom ampersand & die achter elk commando kan worden geplaatst om dat commando op de achtergrond te plaatsen. We hebben ook de gebruiker van het doden opdracht en keken hoe verschillende achtergrondprocessen kunnen worden aangepakt met behulp van de % Bash idioom met een overeenkomend achtergrondprocesnummer zoals % 1 voor [1] enzovoort.

Als je meer wilt weten over Bash in het algemeen, bekijk dan de serie Handige Bash Command Line Tips en Tricks Voorbeelden.

Geniet van je nieuw gevonden Bash-vaardigheden, en als je iets cools doet met achtergrondprocessen, laat dan hieronder een reactie achter!




Niemand heeft nog op dit artikel gereageerd.

Een verzameling nuttige informatie over het Linux-besturingssysteem en nieuwe technologieën
Nieuwe artikelen, praktische tips, gedetailleerde recensies en handleidingen. Voel je thuis in de wereld van het Linux-besturingssysteem