Како да се користи контролата на работата на Bash за управување со процесите во преден план и заднина


Вовед

Во претходното упатство, разговаравме како командите ps, kill и nice може да се користат за контрола на процесите на вашиот систем. Овој водич нагласува како bash, системот Линукс и вашиот терминал се спојуваат за да понудат контрола на процесот и работата.

Оваа статија ќе се фокусира на управување со процесите во преден план и заднина и ќе покаже како да ги искористите функциите за контрола на работата на вашата школка за да стекнете поголема флексибилност во начинот на извршување на командите.

Предуслови

За да го следите ова упатство, ќе ви треба пристап до компјутер со интерфејсот на школка bash. bash е стандардната обвивка на многу оперативни системи базирани на Linux и е достапна на многу оперативни системи слични на Unix, вклучително и macOS. Забележете дека ова упатство е потврдено со користење на виртуелен приватен сервер Линукс со Ubuntu 20.04.

Ако планирате да користите далечински сервер за да го следите ова упатство, ве охрабруваме прво да го комплетирате нашето упатство за почетно поставување сервер. Со тоа ќе поставите безбедно опкружување на серверот - вклучувајќи корисник кој не еroot со привилегии sudo и заштитен ѕид конфигуриран со UFW - што можете да го користите за да го изградите вашиот Linux вештини.

Управување со процеси во преден план

Повеќето процеси што ги започнувате на машината Линукс ќе работат во преден план. Командата ќе започне со извршување, блокирајќи ја употребата на школка за време на процесот. Процесот може да дозволи интеракција со корисникот или може само да помине низ процедура и потоа да излезе. Секој излез стандардно ќе се прикаже во терминалниот прозорец. Ќе разговараме за основниот начин за управување со процесите во преден план во следните подсекции.

Започнување процес

Стандардно, процесите се стартуваат во преден план. Ова значи дека додека програмата не излезе или не ја промени состојбата, нема да можете да комуницирате со школка.

Некои команди во преден план излегуваат многу брзо и речиси веднаш ве враќаат на известувањето за школка. На пример, следнава команда ќе отпечати Hello World на терминалот и потоа ќе ве врати во вашата командна линија:

  1. echo "Hello World"
Output
Hello World

На другите команди во преден план им треба подолго време за да се извршат, блокирајќи го пристапот до школка за нивното времетраење. Ова може да биде затоа што командата врши пообемна операција или затоа што е конфигурирана да работи додека не биде експлицитно запрена или додека не прими друг кориснички влез.

Команда што работи неодредено е алатката top. По стартувањето, ќе продолжи да работи и да го ажурира својот екран додека корисникот не го прекине процесот:

  1. top

Можете да излезете од top со притискање на q, но некои други процеси немаат посебна функција за напуштање. За да ги спречите, ќе мора да користите друг метод.

Прекин на процес

Да претпоставиме дека започнувате едноставна јамка bash на командната линија. Како пример, следнава команда ќе започне циклус што печати Hello World на секои десет секунди. Оваа јамка ќе продолжи засекогаш, сè додека експлицитно не се прекине:

  1. while true; do echo "Hello World"; sleep 10; done

За разлика од top, јамките како оваа немаат клуч \quit. Ќе мора да го запрете процесот со испраќање сигнал. Во Linux, кернелот може да испраќа сигнали до извршувајќи процеси како барање тие да излезат или да ги менуваат состојбите. Терминалите на Linux обично се конфигурирани да го испраќаат сигналот \SIGINT (кратенка од \прекин на сигналот) до тековниот процес во преден план кога корисникот ќе притисне CTRL + C< Комбинација на копчиња /code. Сигналот SIGINT и кажува на програмата дека корисникот побарал прекин со помош на тастатурата.

За да го прекинете циклусот што сте го започнале, држете го копчето CTRL и притиснете го копчето C:

CTRL + C

Јамката ќе излезе, враќајќи ја контролата во школка.

Сигналот SIGINT испратен од комбинацијата CTRL + C е еден од многуте сигнали што може да се испратат до програмите. Повеќето сигнали немаат комбинации на тастатура поврзани со нив и наместо тоа мора да се испратат со помош на командата убиј, која ќе биде опфатена подоцна во ова упатство.

Процеси на суспендирање

Како што беше споменато претходно, процесот на преден план ќе го блокира пристапот до школка за време на нивното извршување. Што ако започнете процес во преден план, но потоа сфатите дека ви треба пристап до терминалот?

Друг сигнал што можете да го испратите е сигналот \SIGTSTP. SIGTSTP е кратенка од \signal terminal stop, и обично се претставува како сигнал број 20. Кога ќе притиснете CTRL + Z, вашиот терминал регистрира команда \suspend, која потоа го испраќа сигналот SIGTSTP во процесот на преден план. Во суштина, ова ќе го паузира извршувањето на командата и ќе ја врати контролата на терминалот.

За илустрација, користете ping за да се поврзете на google.com на секои 5 секунди. Следната команда и претходи на командата ping со command, која ќе ви овозможи да ги заобиколите сите псевдоними на школка што вештачки поставуваат максимално броење на командата:

  1. command ping -i 5 google.com

Наместо да ја прекинете командата со CTRL + C, наместо тоа притиснете CTRL + Z. Со тоа ќе се врати излезот вака:

Output
[1]+ Stopped ping -i 5 google.com

Командата ping е привремено запрена, со што повторно ви се дава пристап до известувањето за школка. Можете да ја користите алатката за процесирање ps за да го прикажете ова:

  1. ps T
Output
PID TTY STAT TIME COMMAND 26904 pts/3 Ss 0:00 /bin/bash 29633 pts/3 T 0:00 ping -i 5 google.com 29643 pts/3 R+ 0:00 ps t

Овој излез покажува дека процесот ping сè уште е наведен, но дека колоната \STAT има \T во неа. Според man-страницата ps, ова значи дека работа што е \запрена со [a] сигнал за контрола на работата.

Овој водич ќе опише како да ги промените состојбите на процесот во поголема длабочина, но засега можете повторно да го продолжите извршувањето на командата во преден план со внесување:

  1. fg

Откако процесот ќе продолжи, прекинете го со CTRL + C:

Управување со заднински процеси

Главната алтернатива за водење процес во преден план е да му се дозволи да се извршува во заднина. Процесот во заднина е поврзан со конкретниот терминал што го започнал, но не го блокира пристапот до школка. Наместо тоа, тој се извршува во заднина, оставајќи го корисникот способен да комуницира со системот додека се извршува командата.

Поради начинот на кој процес во преден план е во интеракција со неговиот терминал, може да има само еден процес во преден план за секој терминален прозорец. Бидејќи процесите во заднина ја враќаат контролата во школката веднаш без да се чека процесот да заврши, многу процеси во заднина можат да работат истовремено.

Почеток на процеси

Можете да започнете процес во заднина со додавање знак за амперсенд (&) на крајот од вашите команди. Ова ѝ кажува на школката да не чека да заврши процесот, туку да започне со извршување и веднаш да го врати корисникот на промпт. Излезот од командата сè уште ќе се прикажува во терминалот (освен ако не е пренасочен), но можете да напишете дополнителни команди додека продолжува процесот на заднина.

На пример, можете да го започнете истиот процес ping од претходниот дел во заднина со внесување:

  1. command ping -i 5 google.com &

Системот за контрола на работа bash ќе го врати излезот вака:

Output
[1] 4287

Потоа ќе го добиете нормалниот излез од командата ping:

Output
PING google.com (74.125.226.71) 56(84) bytes of data. 64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=1 ttl=55 time=12.3 ms 64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=2 ttl=55 time=11.1 ms 64 bytes from lga15s44-in-f7.1e100.net (74.125.226.71): icmp_seq=3 ttl=55 time=9.98 ms

Сепак, можете да пишувате и команди во исто време. Излезот на процесот во заднина ќе се меша меѓу влезот и излезот на вашите процеси во преден план, но нема да се меша во извршувањето на процесите во преден план.

Процеси во заднина на список

За да ги наведете сите запрени или задни процеси, можете да ја користите командата jobs:

  1. jobs

Ако сè уште ја имате претходната команда ping работи во позадина, излезот на командата jobs ќе биде сличен на овој:

Output
[1]+ Running command ping -i 5 google.com &

Ова покажува дека моментално имате единствен процес во заднина што работи. [1] го претставува спецификациите за работа или бројот на задачата на командата. Ова може да го упатите со други команди за контрола на работните задачи и процесите, како што се убијте, fg и bg со тоа што ќе му претходите на бројот на работата со знак за процент. Во овој случај, ќе ја наведете оваа работа како %1.

Запирање на процесите во заднина

Можете да го прекинете тековниот процес во заднина на неколку начини. Наједноставниот начин е да се користи командата убиј со поврзаниот број на работа. На пример, можете да го убиете вашиот процес на заднина што работи со впишување:

  1. kill %1

Во зависност од тоа како е конфигуриран вашиот терминал, веднаш или следниот пат кога ќе притиснете ENTER, статусот на завршување на работата ќе се појави на вашиот излез:

Output
[1]+ Terminated command ping -i 5 google.com

Ако повторно ја проверите командата jobs, нема да има тековни задачи.

Промена на состојби на процесот

Сега кога знаете како да ги започнете и стопирате процесите во заднина, можете да научите за промена на нивната состојба.

Овој водич веќе наведе еден начин за промена на состојбата на процесот: запирање или суспендирање на процес со CTRL + Z. Кога процесите се во оваа стопирана состојба, можете да преместите процес во преден план во позадина или обратно.

Преместување на процесите во преден план во позадина

Ако заборавите да завршите команда со & кога ќе ја стартувате, сè уште можете да го преместите процесот во позадина.

Првиот чекор е повторно да го запрете процесот со CTRL + Z. Откако процесот ќе се запре, можете да ја користите командата bg за да го започнете повторно во позадина:

  1. bg

Повторно ќе ја добиете линијата за статусот на работното место, овој пат со додаден знак:

Output
[1]+ ping -i 5 google.com &

Стандардно, командата bg работи на најновиот прекинат процес. Ако сте запреле повеќе процеси по ред без да ги започнете повторно, можете да упатувате конкретен процес според бројот на неговата работа за да го преместите правилниот процес во позадина.

Забележете дека не сите команди можат да бидат во позадина. Некои процеси автоматски ќе завршат ако откријат дека се започнати со стандардниот влез и излез директно поврзани со активен терминал.

Преместување на процесите во заднина во преден план

Можете исто така да ги преместите процесите во заднина во преден план со внесување fg:

  1. fg

Ова работи на вашиот најнов процес во позадина (означен со + во излезот на командата jobs). Веднаш го суспендира процесот и го става во преден план. За да наведете друга работа, користете го нејзиниот број за работа:

  1. fg %2

Откако задачата е во преден план, можете да ја убиете со CTRL + C, да ја оставите да заврши или да ја суспендирате и повторно да ја преместите во позадина.

Справување со SIGHUPs

Без разлика дали процесот е во заднина или во преден план, тој е прилично цврсто врзан со терминалниот пример што го започнал. Кога терминалот се затвора, тој обично испраќа сигнал SIGHUP до сите процеси (преден план, позадина или запрени) кои се поврзани со терминалот. Ова сигнализира процесите да завршат бидејќи нивниот контролен терминал наскоро ќе биде недостапен.

Сепак, може да има моменти кога сакате да затворите терминал, но да ги одржувате процесите во заднина да работат. Постојат голем број начини да се постигне ова. Еден од пофлексибилните начини е да се користи терминален мултиплексер како dtach.

Сепак, ова не е секогаш опција. Понекогаш овие програми не се достапни или веќе сте го започнале процесот што ви треба за да продолжите да работите. Понекогаш овие дури може да бидат претерани за она што треба да го постигнете.

Користење nohup

Ако знаете кога го започнувате процесот дека ќе сакате да го затворите терминалот пред да заврши процесот, можете да го започнете со помош на командата nohup. Ова го прави започнатиот процес имун на сигналот SIGHUP. Ќе продолжи да работи кога терминалот ќе се затвори и ќе биде преназначен како дете на иницијалниот систем:

  1. nohup ping -i 5 google.com &

Ова ќе врати линија како следната, што покажува дека излезот од командата ќе биде запишан во датотека наречена nohup.out:

Output
nohup: ignoring input and appending output to ‘nohup.out’

Оваа датотека ќе биде сместена во вашиот тековен работен директориум ако може да се запише, но во спротивно ќе биде сместена во вашиот домашен директориум. Ова е за да се осигура дека излезот не се губи ако терминалниот прозорец е затворен.

Ако го затворите терминалниот прозорец и отворите друг, процесот сè уште ќе работи. Нема да го најдете во излезот од командата jobs бидејќи секоја терминална инстанца одржува сопствена независна редица за работа. Затворањето на терминалот ќе предизвика ping работата да биде уништена иако сè уште работи ping процесот.

За да го уништите процесот ping, ќе треба да го најдете неговиот ID на процес (или \PID). Тоа можете да го направите со командата pgrep (исто така постои и Командата pkill, но овој метод од два дела гарантира дека само го уништувате планираниот процес). Користете pgrep и знамето -a за пребарување за извршната датотека:

  1. pgrep -a ping
Output
7360 ping -i 5 google.com

Потоа можете да го убиете процесот со упатување на вратениот PID, што е бројот во првата колона:

  1. kill 7360

Можеби ќе сакате да ја отстраните датотеката nohup.out ако повеќе не ви треба.

Користење на отфрлање

Командата nohup е корисна, но само ако знаете дека ќе ви треба во моментот кога ќе го започнете процесот. Системот за контрола на работата bash обезбедува други методи за постигнување слични резултати со вградената команда disown.

Командата disown, во својата стандардна конфигурација, отстранува задача од редот за задачи на терминалот. Ова значи дека повеќе не може да се управува со помош на механизмите за контрола на работните места што се дискутирани претходно во ова упатство, како што се fg, bg, CTRL + Z, CTRL + C. Наместо тоа, работата веднаш ќе се отстрани од списокот на излезот jobs и повеќе нема да биде поврзана со терминалот.

Командата се повикува со наведување на број на работа. На пример, за веднаш да се откажете од работата 2, можете да напишете:

  1. disown %2

Ова го остава процесот во состојба која не е различна од онаа на процесот nohup откако контролниот терминал е затворен. Исклучок е дека секој излез ќе се изгуби кога контролниот терминал ќе се затвори ако не се пренасочува во датотека.

Обично, не сакате целосно да го отстраните процесот од контрола на работата ако веднаш не го затворите прозорецот на терминалот. Наместо тоа, можете да го пренесете знамето -h на процесот disown за да го означите процесот да ги игнорира сигналите SIGHUP, но во спротивно да продолжи како редовна работа:

  1. disown -h %1

Во оваа состојба, можете да користите нормални механизми за контрола на работата за да продолжите да го контролирате процесот до затворање на терминалот. По затворањето на терминалот, уште еднаш ќе останете заглавени со процес без каде да излезете ако не сте се пренасочиле на датотека кога ја стартувате.

За да го надминете тоа, можете да се обидете да го пренасочите излезот од вашиот процес откако тој веќе работи. Ова е надвор од опсегот на овој водич, но овој пост дава објаснување за тоа како би можеле да го направите тоа.

Користење на опцијата huponexit Shell

bash има уште еден начин за избегнување на проблемот SIGHUP за детски процеси. Опцијата за школка huponexit контролира дали bash ќе го испрати своето дете да го обработи сигналот SIGHUP кога ќе излезе.

Забелешка: опцијата huponexit влијае на однесувањето на SIGHUP само кога завршувањето на сесијата на школка се иницира од самата школка. Некои примери кога ова важи се кога командата излез или CTRL + D се притиска во сесијата.

Кога сесијата на школка ќе заврши преку самата терминална програма (преку затворање на прозорецот итн.), командата huponexit ќе има не влијание. Наместо bash да одлучува дали да го испрати сигналот SIGHUP, самиот терминал ќе го испрати сигналот SIGHUP до bash, кој потоа правилно ќе го пропагира сигналот до неговите втори процеси.

И покрај гореспоменатите предупредувања, опцијата huponexit е можеби една од најлесните за управување. Можете да одредите дали оваа функција е вклучена или исклучена со внесување:

  1. shopt huponexit

За да го вклучите, напишете:

  1. shopt -s huponexit

Сега, ако излезете од вашата сесија со пишување exit, сите ваши процеси ќе продолжат да работат:

  1. exit

Ова ги има истите предупредувања за излезот на програмата како и последната опција, затоа проверете дали сте го пренасочиле излезот на вашите процеси пред да го затворите терминалот ако тоа е важно.

Заклучок

Учењето за контрола на работата и како да управувате со процесите во преден план и позадина ќе ви даде поголема флексибилност при извршување на програми на командната линија. Наместо да морате да отворите многу терминални прозорци или SSH сесии, честопати можете да поминете со рано запирање на процесите или преместување во позадина по потреба.