Запуск та обробка фонових процесів: керування завданнями. Процеси та керування завданнями Запуск команди у фоні linux

💖 Подобається?Поділися з друзями посиланням

Запуск та обробка фонових процесів: управління завданнями

Ви, напевно, помітили, що після того, як ви ввели команду в Terminal "е, вам зазвичай потрібно дочекатися завершення її роботи, перш ніж shell поверне вам керування. Це означає, що ви запустили команду впріоритетному режимі . Проте трапляються випадки, коли це небажано.

Допустимо, наприклад, що ви вирішили рекурсивно скопіювати один великий каталог в інший. Ви також вирішили ігнорувати помилки, тому ви перенаправили канал помилок у/dev/null :

cp -R images/ /shared/ 2>/dev/null

Виконання такої команди може зайняти кілька хвилин, поки вона не виконається повністю. У вас є два варіанти вирішення: перший - жорстокий, що передбачає зупинку (вбивання) команди, а потім повторне її виконання, але вже у відповідний час. Для цього натисніть Ctrl+c : при цьому процес буде завершено, а ви повернетеся назад до рядка запрошення. Але зачекайте, поки не робіть цього! Читайте далі.

Допустимо, ви хочете, щоб команда виконувалася, а ви займалися чимось іншим. Рішенням буде запуск процесу вфоновому режимі . Для цього натисніть Ctrl+z , щоб призупинити процес:

При цьому процес продовжить свою роботу, але вже як фонове завдання, як це зазначено знаком & (амперсанд) наприкінці рядка. Потім ви повернетеся назад у рядок запрошення та зможете продовжити роботу. Процес, який виконується як фонова задача, або фоновому режимі, називається фоновимзавданням .

Звичайно, ви можете відразу запускати процеси як фонові завдання, додаючи знак & наприкінці команди. Наприклад, ви можете запустити команду копіювання каталогу у фоновому режимі, набравши:

cp -R images/ /shared/ 2>/dev/null &

Якщо хочете, ви також можете відновити цей процес у пріоритетному режимі та дочекатися його завершення, набравшиfg (ForeGround - Пріоритетний). Щоб перевести його назад у фоновий режим, введіть наступну послідовність Ctrl+z , bg .

У такий спосіб ви можете запустити кілька завдань: кожній команді буде присвоєно номер завдання. Команда shell "а jobs виводить список усіх завдань, пов'язаних із поточним shell Перед завданням ставиться знак + , що вказує на останній процес, запущений у фоновому режимі. Для відновлення конкретного завдання у пріоритетний режим ви можете ввести командуfg , де - номер завдання, наприклад,fg 5 .

Служба з терміналом Linux за промовчанням ведеться в однозадачному режимі. Це означає, що будь-яка запущена бригада блокує термінал до завершення. Такий підхід не зручний при запуску програм, які запитують тривалий час виконання. Цю проблемуможна вирішити двома способами: розкрити додаткове вікнотерміналу та виконати в ньому іншу команду або використовувати фоновий режим. Всі нинішні операційні системи, у тому числі і Linux, є багатозадачними, що передбачає можливість синхронного виконання безлічі програм.

Як запустити бригаду у фоновому режимі, щоб одразу отримати доступ до інтерфейсу командного рядка? Бригада, виконання якої заплановано примусово, називається фоновим процесом. Фонові процеси не відображаються на екрані. Наприклад, сервер HTTPD Apache працює у фоновому режимі для обслуговування веб-сторінок. У режимі низького пріоритету можна помістити скрипт оболонки або будь-яку команду. Завдання (наприклад, бригаду або скрипт) можна перевести у фоновий режим, додавши символ & в кінець командного рядка. Цей оператор переводить команду у фоновий режим та звільняє місце у терміналі. Бригада, що виконується у фоновому режимі, називається завданням. Під час роботи фонової команди можна виконувати будь-які інші команди. Синтаксис виглядає так:

command & script-name & /path/to/command arg1 arg2 & command-1 | Command-2 arg1 & Command-1 | command-2 -arg1 -arg2 >/path/to/output &

Для пуску програм у фоновому режимі, який не блокує вікно терміналу, необхідно використовувати спеціальний інструктор «&». Поставте цей символ у кінці рядка після вказівки прізвища команди, опцій і вхідних параметрів. У загальному вигляді цю послідовність можна вписати як «ім'я_команди -опція вхідний_параметр &».

ls ~/* > ~/test-file.txt &
18960

Після натискання кнопки Enter програма автоматично запуститься у фоновому режимі. При цьому термінал покаже рядок з наступним вмістом «[номер_задания] ідентифікатор_процесу», і видасть запрошення до введення нової команди.

Знайти команди, що працюють у фоновому режимі в Linux

Виконайте наступну бригаду:

Приклад виведення даних:

Running find / -iname "*.c" 2> /dev/null > /tmp/output.txt &
+ Running grep -R "hostNamed" / 2> /dev/null > /tmp/grep.txt &

Де та ідентифікатори доручень.

Щоб відобразити ідентифікатори процесів для ідентифікаторів завдань, крім стандартних наведень, передайте параметр -l:

Приклад виведення даних:

7307 Running find / -iname "*.c" 2> /dev/null > /tmp/output.txt &
+ 7324 Running grep -R "hostNamed" / 2> /dev/null > /tmp/grep.txt &

Щоб відобразити лише ідентифікатори процесів, введіть:

Приклад виведення даних:

Закінчити виконання команд, що працюють у фоновому режимі

Для примусового чи поступового завершення процесу слід використовувати команду kill. Синтаксис виглядає так:

kill PID
kill -15 PID
kill -9 PID
killall process-Name-Here
killall -15 process-Name-Here
killall -9 процесів-Name-Here

Повернення програми на пріоритетний режим на Linux

Linux дозволяє не тільки запускати програми у фоновому режимі, але і за бажанням повертати до звичного виконання. Для цього існує два інструменти: команда ( Команда – група осіб, об'єднана загальними мотивами, інтересами) fg та оператор %. Принцип їхнього зусилля гранично простий. fg вимагає вказати номер завдання як параметр, а до % його потрібно підставити відразу після оператора без пропусків.

find / -name .ini 2> ~/results.txt &
19090
fg 1
bash: fg: завдання закінчилося
+ Вихід з 1 find /-name .ini 2> ~/results.txt

По суті, операційна система складається з ядра і величезного набору програм, які призначені для виконання різних завдань, обслуговування системи та задоволення потреб користувача. Майже вся взаємодія користувача та операційної системивиконується за допомогою програм. Тому новачкам важливо зрозуміти як запустити програму на Linux, що відбувається під час запуску та які є способи запуску.

Перед тим, як ми перейдемо до запуску програм, потрібно спочатку зрозуміти що являє собою програма. У Linux програми відрізняються від інших файлів лише тим, що для них встановлено прапорцію виконання. Я вже докладно писав про це у статті тому не повторюватимуся.

Усі програми можна розділити на кілька типів:

  • Бінарні програми- містять інструкції процесору вже готові до виконання, більшість програм знаходяться у такому форматі, вони швидкі та виконуються одразу ж системою;
  • Програми на байт-коді- це вже не процесорні інструкції, а інструкції певної віртуальної машини, яка може їх виконувати без віртуальної машини такі команди не можуть бути виконані. Такі програми споживають більше ресурсів, але теж досить швидкі, їхня перевага в тому, що вони можуть виконуватися без зміни скрізь, де може працювати віртуальна машина. До таких програм можна віднести програми Java.
  • Скриптові програми- ці програми складаються з набору команд як звичайного тексту, які виконує спеціальний інтерпретатор. Такі програми більш повільні, зате вони простіше в розробці і їх код можна легко і швидко змінити.

А зараз перейдемо до запуску програм.

Запуск програм у терміналі

Спочатку в операційних системах Unix і Linux був графічного інтерфейсу, тому програми запускалися командами з терміналу. Зараз це також можливо і досить активно використовується досвідченими користувачами. Синтаксис запуску програми виглядає так:

/шлях/до/файлу/програмипараметри

Параметри вказуються лише, коли вони потрібні, але завжди оболонка має знати повний шлях до програми. Все що після імені програми та пропуску - це параметри. Ви, мабуть, вже помітили, що ми не вказуємо повний шлях при виконанні програм. Це було б дуже довго та незручно.

Розробники вигадали обхідний шлях. Була створена змінна PATH, в якій зберігаються всі шляхи до папок, де зазвичай знаходяться програми - /bin, /sbin, /usr/bin, /usr/sbin і так далі. Ви можете переглянути її вміст командою:

Коли ви набираєте ім'я програми, система шукає виконуваний файл з таким ім'ям по всіх папках з PATH і якщо знаходить - то виконує. Якщо такого файлу немає, то видається повідомлення - command not found. Таким чином, щоб запустити одну з системних програмдостатньо набрати ім'я її виконуваного файлу, наприклад:

І можна передати параметри після пропуску:

Коли програма не в цих каталогах, потрібно вказати до неї повний шлях:

/usr/local/bin/ls1

Якщо ж ви хочете запустити програму через термінал ubuntu, яка знаходиться в поточній папці, ситуація буде трохи інший. Система виконує лише пошук папок зі змінної PATH, в поточній директорії вона не шукає. Тому, якщо ви наберете ім'я файлу, що виконується, то отримаєте помилку. Потрібно вказувати повний шлях, як ви пам'ятаєте./:

Іноді виникає необхідність передати програмі, якісь особливі . Наприклад, змінна EDITOR вказує який текстовий редакторпотрібно використовувати за промовчанням. Ви можете вказати ім'я змінної та її значення перед ім'ям команди, використовуючи синтаксис:

ім'я_змінної = значення команда

Наприклад:

EDITOR=nano visudo

За замовчуванням ця команда відкриває налаштування у редакторі Vim, але з цією змінної оточенняНалаштування відкриються в редакторі nano.

Запуск програм від імені іншого користувача

Ви вже знаєте як запустити програму в терміналі linux, а що щодо інших користувачів? У Windows досить часто використовується запуск програм від імені адміністратора, щоб програма могла отримати більше прав доступу в системі. У Linux для цього використовується утиліта sudo. Її ім'я можна розшифрувати як s witch u ser do- Змінити користувача і виконати. За замовчуванням утиліта виконує команду від імені суперкористувача root:

sudo команда
sudo whoami

Але за допомогою опції -u можна виконати програму від імені будь-якого користувача, зареєстрованого у системі:

sudo -u ім'я_користувача команда
sudo -u postgres whoami

Команда whoami (хто я) виводить ім'я користувача.

Як запустити програму у фоні

Іноді виникає необхідність запустити програму, що довго виконується, в терміналі так, щоб вона не заважала далі працювати. Для цього можна використовувати запуск програми у фоновому режимі linux:

ім'я_програми &

Наприклад:

dd if=/dev/zero of=~/file count=100000 &

Система виведе PID, унікальний ідентифікатор програми, який ви потім можете використовувати, щоб закрити її :

Як запустити скрипт у Linux

Ми вже говорили, що програми діляться на бінарні та інтерпретовані. Раніше ми говорили лише про бінарні програми. Для запуску інтерпретованих потрібен безпосередньо інтерпретатор, до таких програм відносяться написані мовами, як Java, Python, Perl, Ruby, PHP, NodeJS і багатьох інших. Синтаксис запуску такої програми відрізняється:

інтерпретатор /шлях/до/файлу/програмипараметри

Різні інтерпретатори поводяться по-різному, тому краще відразу вказувати повний шлях до програми. Python зазвичай підхоплює скрипти з поточної папки без повного шляху:

python hellowrld.py

А Java програми потрібно запускати так:

java -jar program.jar

Для файлів інтерпретованих програм прапор виконуваності необов'язковий, оскільки вони передаються як параметра основний програмі. Тільки Bash скриптистановлять виняток. Ви можете запустити скрипт інтерпретатором:

Або ж просто набрати шлях до скрипту:

Оболонка сама визначає свої скрипти по прапору виконуваності та виконує їх. Якщо прапор виконуваності не встановлений, його варто додати:

sudo chmod u+x ./script.sh

Тому і для більшості інтерпретованих програм створено прості sh скрипти якими їх можна швидко запустити.

Запуск програм Linux у графічному інтерфейсі

Набагато зручніше запускати програми через графічний інтерфейс. Якщо консольні програми так запускати неможливо, то для всіх графічних утиліт існують ярлики, які можна знайти в головному меню системи:

Крім того, ви можете запустити програму з файлового менеджера, подвійним натисканням мишею, але тоді для неї обов'язково має бути встановлений прапор виконуваності.

Так само працює запуск скриптів у графічному інтерфейсі. Ви можете знайти всі ярлики з меню у каталозі /usr/share/applications/. Будь-яку програму можна запустити подвійним клацанням звідси. Але давайте подивимося, що знаходиться всередині ярлика, для цього відкрийте його в текстовому редакторі:


Крім того, у рядку Exec вказана команда, яка виконує запуск програми linux, коли ви робите подвійний клік на ярлику. Ви можете взяти один із існуючих ярликів і зробити на його основі свій. Тут наведено просто ім'я програми. Але важливо помітити, що краще вказувати повний шлях у таких місцях, як ярлики, скрипти, cron і так далі це зменшить кількість помилок, оскільки ви не можете знати, чи перевіряє система в цьому випадку PATH або шукає програму тільки в поточному каталозі. Тепер ви знаєте все про те, як запустити програму на linux.

Висновки

У цій статті ми розглянули, як запустити програму через термінал ubuntu або в інших дистрибутивах Linux. Незважаючи на те, що це здається дуже простою темою, тут є свої цікаві моменти, які можуть бути корисними. Але ви про них знаєте. Якщо у вас залишилися питання, запитуйте у коментарях!

Як і будь-яка інша багатозадачна система, Linux одночасно виконує кілька процесів. Взагалі, не буду вводити Вас в оману, тому що звичайний однопроцесорний комп'ютер може виконувати тільки одне завдання Наразічасу, тому Linux ставить процеси в чергу на виконання.

Існує кілька основних команд для управління процесами

  • ps- Виводити список запущених процесів
  • kill- Відправляє сигнал на один або кілька процесів (в основному, щоб "вбити" їх)
  • jobs- альтернативний шлях для перегляду процесів запущених Вами
  • bg- ставить виконання процесу у фоновий режим
  • fg- виводить виконання процесу із фонового режиму

Хоча може здатися, що ці знання є досить абстрактними, але вони можуть знайти своє практичне застосуваннянавіть для середнього користувача, який використовує графічний інтерфейс. Можливо Ви ще не знаєте, що більшість графічних програм(якщо не всі) можна запустити командним рядком. Для прикладу спробуємо запустити браузер, думаю у більшості linux-оїдів стоїть або Google Chromeабо FireFox

Enej@linux:/home/pub/www/vv$ google-chrome Створення нового window in existing browser session.

Можна вказати URL, яку Ви бажаєте відкрити

Enej@linux:/home/pub/www/vv$ google-chrome http://сайт Created new window in existing browser session.

У мене вже запущений Хром через графічний інтерфейс, тому браузер повідомляє, що створюється нове вікно в існуючій сесії і віддає управління командному рядку. Або, наприклад, якщо потрібно відкрити графічний файловий менеджерз правами рута (приклад працюватиме для графічної оболонки Gnome із встановленим Nautilus)

Enej@linux:/home/pub/www/vv$ sudo nautilus /root/ password for enej:

Оскільки процес був запущений не у фоновому режимі, то у цьому вікні терміналу Ви більше не можете виконувати будь-які дії (щоб завершити процес можна натиснути CTRL + C).

Фоновий режим

Для того, щоб було простіше жити, при запуску графічних програм або процесів, які можуть довго працювати, зазвичай їх виконання ставлять у фоновий режим, наприклад, запустимо браузер у фоновому режимі

Enej@linux:/home/pub/www/vv$ google-chrome http://сайт & 9248

Знак амперсанта ( & ) в кінці виклику команди означає, що виконання процесу потрібно помістити у фоновий режим. У такому випадку залишається можливість працювати з цим вікном терміналу.

Але раптом ви забули поставити ампресант наприкінці виклику, тоді існує інший спосіб. Потрібно спочатку зупинити виконання, натиснувши CTRL + Z, тоді отримуємо управління командним рядком і можемо викликати команду bg, яка поставимо останній запущений процесу фоновому режимі. Сказане на прикладі

Enej@linux:/home/pub/www/vv$ google-chrome http://сайт ^Z + Stopped google-chrome http://сайт enej@linux:/home/pub/www/vv$ bg + google- chrome http://сайт &

Команда fgвиводить останній запущений процес із фонового режиму.

Список запущених процесів

Оскільки тепер Ви вмієте ставити команди у фоновий режим, було добре переглянути їх список. Для цього використовується команда jobsабо потужніша ps

Enej@linux:/home/pub/www/vv$ jobs - Running nm-applet & (wd: ~/bin) + Running google-chrome http://сайт & enej@linux:/home/pub/www/vv $ ps PID TTY TIME CMD 2304 pts/0 00:00:02 bash 11104 pts/0 00:00:01 chrome 11108 pts/0 00:00:00 chrome 11110 pts/0 00:00:00 00:00:00 chrome 12088 pts/0 00:00:00 ps 21165 pts/0 00:00:27 nm-applet

Як "вбити" процес?

Якщо процес перестає відповідати на події (тобто завис), його потрібно примусово "вбити". Думаю ті, хто використовує FireFox стикалися з цим. Для таких завдань використовується команда kill. Але для початку потрібно якимось чином визначити процес. Для цього можна використати команду jobsабо ps. За допомогою першої можна дізнатися номер процесу, за допомогою другого його ідентифікатор.

Enej@linux:/home/pub/www/vv$ google-chrome http://freaksidea..com & 15181 enej@linux:/home/pub/www/vv$ ps PID TTY TIME CMD 2304 pts/0 00: 00:02 bash 15181 pts/0 00:00:00 chrome 15238 pts/0 00:00:00 ps 21165 pts/0 00:00:27 nm-applet enej@linux:/home/pub/www/vv$ill 15181

Команди fgі bgяк перший аргумент можуть приймати номер запущеного процесу, для його наступного введення/виведення в/з фонового режиму.

Детальніше про kill

Насправді команда killвикористовується для надсилання різних сигналів процесам. Просто в більшості випадків цей сигнал каже команді, що вона має завершитися. Якщо програми правильно написані, то вони прослуховують різні сигнали від операційної системи та відповідають на них. Наприклад, текстовий редактор повинен прослуховувати будь-який сигнал, який повідомляє, що користувачів виходить із системи або що комп'ютер вимикається. Коли він (текстовий редактор) "почув" такий сигнал, він має зберегти відкриті документиперед тим, як закінчити свою роботу. Команда killвміє відсилати кілька типів сигналів, щоб дізнатись які, введіть kill -l. Нижче наведено список найчастіше використовуваних сигналів (число в дужках - номер сигналу)

  • SIGNUP(1)- спочатку був призначений для того, щоб інформувати програму про втрату зв'язку з терміналом, що управляє (термінали часто підключалися до системи за допомогою модемів, так що назва сигналу походить від hung up - повісити трубку). Сигнал SIGHUP надсилається додатку так само й у тому випадку, якщо процес-лідер сесії завершив свою роботу. Багато програм-демони, у яких немає лідера сесії, так само обробляють цей сигнал. У відповідь отримання SIGHUP демон зазвичай перезапускається (чи просто повторно читає файл конфігурації). За промовчанням програма, що отримала цей сигнал, завершується.
  • SIGINT(2)- зазвичай надсилається процесу, якщо користувач терміналу дав команду перервати процес (зазвичай ця команда - поєднання клавіш Ctrl + C)
  • SIGTERM(15)- Викликає "ввічливе" завершення програми. Отримавши цей сигнал, програма може виконати необхідні перед завершенням операції (наприклад, зберегти відкриті документи). Отримання SIGTERM свідчить не про помилку у програмі, а про бажання ОС чи користувача завершити її.
  • SIGKILL(9)- Викликає примусове завершенняроботи програми. Програма неспроможна ні обробити, ні ігнорувати цей сигнал.

За замовчуванням команда killвідправляє SIGTERMсигнал, але можна вказати номер сигналу або його ім'я. Допустимо, що у Вас завис Chrome (у мене іноді флеш плеєр перестає адекватно працювати)

Enej@linux:/home/pub/www/vv$ google-chrome http://сайт & 22066 enej@linux:/home/pub/www/vv$ jobs - Running nm-applet & (wd: ~/bin) + Running google-chrome http://сайт & enej@linux:/home/pub/www/vv$ kill -SIGTERM %2 enej@linux:/home/pub/www/vv$ kill -SIGKILL %2 enej@linux :/home/pub/www/vv$ kill -9 %2

P.S.: думаю дуже цікавим для початківців буде 2 команди: notify-send(відправляє повідомлення через графічну оболонку, у Gnome з'являється зверху праворуч) і espeak(Синтезатор мови). Якщо якийсь із них у Вас немає, встановити можна за допомогою команди apt-get

Enej@linux:/home/pub/www/vv$ sudo apt-get install espeak notify-send

Минулого разу ми говорили про роботу з потоками введення, виведення та помилок у bash-скриптах, про дескриптори файлів та про перенаправлення потоків. Зараз ви знаєте досить багато для того, щоб писати щось своє. На даному етапі освоєння bash у вас можуть виникнути питання про те, як управляти працюючими скриптами, як автоматизувати їх запуск.

Досі ми вводили імена скриптів у командний рядок і натискали Enter, що призводило до негайного запуску програм, але це не єдиний спосіб виклику сценаріїв. Сьогодні ми поговоримо про те, як скрипт може працювати з сигналами Linux, про різні підходи до запуску скриптів та управління ними під час роботи.

Сигнали Linux

У Linux існує понад три десятки сигналів, які генерує система або програми. Ось список найчастіше використовуваних, які, напевно, стануть у нагоді при розробці сценаріїв командного рядка.
Код сигналу
Назва
Опис
1
SIGHUP
Закриття терміналу
2
SIGINT
Сигнал зупинення процесу користувачем з терміналу (CTRL+C)
3
SIGQUIT
Сигнал зупинення процесу користувачем з терміналу (CTRL+\) з дампом пам'яті
9
SIGKILL
Безумовне завершення процесу
15
SIGTERM
Сигнал запиту завершення процесу
17
SIGSTOP
Примусове зупинення виконання процесу, але не завершення його роботи
18
SIGTSTP
Призупинення процесу з терміналу (CTRL+Z), але не завершення роботи
19
SIGCONT
Продовження виконання раніше зупиненого процесу

Якщо оболонка bash отримує сигнал SIGHUP, коли ви закриваєте термінал, вона завершує роботу. Перед виходом вона відправляє сигнал SIGHUP всім запущеним у ній процесам, включаючи скрипти, що виконуються.

Сигнал SIGINT призводить до тимчасової зупинки роботи. Ядро Linux перестає виділяти оболонці процесорний час. Коли це відбувається, оболонка повідомляє процеси, надсилаючи їм сигнал SIGINT .

Bash-скрипти не контролюють ці сигнали, але вони можуть розпізнавати їх і виконувати деякі команди для підготовки скрипту до наслідків, викликаних сигналами.

Надсилання сигналів скриптам

Оболонка bash дозволяє відправляти скриптам сигнали, користуючись комбінаціями клавіш на клавіатурі. Це виявляється дуже доречним якщо потрібно тимчасово зупинити скрипт або завершити його роботу.

Завершення роботи процесу

Комбінація клавіш CTRL + C генерує сигнал SIGINT і відправляє його всім процесам, що виконуються в оболонці, що призводить до завершення їхньої роботи.

Виконаємо в оболонці таку команду:

$ sleep 100
Після цього завершимо її роботу комбінацією клавіш CTRL+C.


Завершення роботи процесу з клавіатури

Тимчасова зупинка процесу

Комбінація клавіш CTRL + Z дозволяє згенерувати сигнал SIGTSTP, який припиняє роботу процесу, але не завершує його виконання. Такий процес залишається у пам'яті, його роботу можна відновити. Виконаємо в оболонці команду:

$ sleep 100
І тимчасово зупинимо її комбінацією клавіш CTRL+Z.


Призупинення процесу

Число в квадратних дужках- Це номер завдання, який оболонка призначає процесу. Оболонка розглядає процеси, що виконуються в ній, як завдання з унікальними номерами. Перший процес призначається номер 1, другий - 2, і так далі.

Якщо ви призупините завдання, прив'язане до оболонки, і спробуєте вийти з неї, bash видасть попередження.

Переглянути призупинені завдання можна такою командою:

Ps -l


Список завдань

У колонці S виводить стан процесу для призупинених процесів виводиться T . Це вказує на те, що команда або припинена, або перебуває в стані трасування.

Якщо потрібно завершити роботу зупиненого процесу, можна скористатися командою kill. Подробиці про неї можна почитати.

Виглядає її виклик так:

Kill processID

Перехоплення сигналів

Для того, щоб увімкнути в скрипті відстеження сигналів Linux, використовується команда trap. Якщо скрипт отримує сигнал, вказаний під час виклику цієї команди, він обробляє його самостійно, при цьому оболонка такий сигнал не оброблятиме.

Команда trap дозволяє скрипту реагувати на сигнали, інакше їх обробка виконується оболонкою без участі.

Розглянемо приклад, у якому показано, як із виклику команди trap задається код, який треба виконати, і перелік сигналів, розділених пробілами, які хочемо перехопити. В даному випадку це лише один сигнал:

#!/bin/bash trap "echo " Trapped Ctrl-C"" SIGINT echo Цей тест script count=1 while [ $count -le 10 ] do echo "Loop #$count" sleep 1 count=$(($ count + 1)) done
Команда trap, використана в цьому прикладі, виводить текстове повідомлення щоразу, коли вона виявляє сигнал SIGINT, який можна згенерувати, натиснувши Ctrl+C на клавіатурі.


Перехоплення сигналів

Щоразу, коли ви натискаєте клавіші CTRL + C , скрипт виконує команду echo , вказану під час виклику trace замість того, щоб дозволити оболонці завершити його роботу.

Перехопити сигнал виходу зі скрипта можна, використовуючи під час виклику команди trap ім'я сигналу EXIT:

#!/bin/bash trap "echo Goodbye..." EXIT count=1 while [ $count -le 5 ] do echo "Loop #$count" 1 count=$(($count + 1)) done


Перехоплення сигналу виходу із скрипту

При виході зі скрипту, чи це нормальне завершення його роботи або завершення, викликане сигналом SIGINT , спрацює перехоплення і оболонка виконає команду echo .

Модифікація перехоплених сигналів та скасування перехоплення

Для модифікації сигналів, що перехоплені скриптом, можна виконати команду trap з новими параметрами:

#!/bin/bash trap "echo "Ctrl-C is trapped."" SIGINT count=1 while [ $count -le 5 ] do echo "Loop #$count" 1 count=$(($count + 1) ) done trap "Echo "I modified the trap!""


Модифікація перехоплення сигналів

Після модифікації сигнали будуть оброблятися по-новому.

Перехоплення сигналів можна і скасувати, для цього достатньо виконати команду trap, передавши їй подвійне тире та ім'я сигналу:

#!/bin/bash trap "echo "Ctrl-C is trapped."" SIGINT count=1 while [ $count -le 5 ] do echo "Loop #$count" 1 count=$(($count + 1) ) done trap -- SIGINT echo "Якщо вимкнуто trap" count=1 while [ $count -le 5 ] do echo "Second Loop #$count" sleep 1 count=$(($count + 1)) done
Якщо скрипт отримає сигнал до скасування перехоплення, він обробить його так, як задано чинній команді trap. Запустимо скрипт:

$./myscript
І натиснемо CTRL+C на клавіатурі.


Сигнал, перехоплений до скасування перехоплення

Перше натискання CTRL + C довелося на момент виконання скрипта, коли перехоплення сигналу було чинним, тому скрипт виконав призначену сигналу команду echo . Після того, як виконання дійшло до команди скасування перехоплення, команда CTRL+C спрацювала звичайним чином, завершивши роботу скрипту.

Виконання сценаріїв командного рядка у фоновому режимі

Іноді bash-скриптам потрібно багато часу для виконання якогось завдання. При цьому вам знадобиться можливість нормально працювати в командному рядку, не чекаючи завершення скрипту. Реалізувати це не так уже й складно.

Якщо ви бачили список процесів, що виводиться командою ps, ви могли помітити процеси, які виконуються на тлі і не прив'язані до терміналу.
Напишемо такий скрипт:

#!/bin/bash count=1 while [ $count -le 10 ] do sleep 1 count=$(($count + 1)) done
Запустимо його, вказавши після імені символ амперсанда (&):

$ ./myscipt &
Це призведе до того, що його буде запущено як фоновий процес.


Запуск скрипту у фоновому режимі

Скрипт буде запущений у фоновому процесі, у термінал виведеться його ідентифікатор, а коли його виконання завершиться, ви побачите повідомлення про це.

Зверніть увагу на те, що хоча скрипт виконується у фоні, він продовжує використовувати термінал для виведення повідомлень у STDOUT і STDERR , тобто текст, що виводиться ним, або повідомлення про помилки можна буде побачити в терміналі.


Список процесів

При такому підході, якщо вийти з терміналу, скрипт, що виконується у фоні, також завершить роботу.

Що, якщо потрібно, щоб скрипт продовжував працювати і після закриття терміналу?

Виконання скриптів, які не завершують роботу під час закриття терміналу

Скрипти можна виконувати у фонових процесах навіть після виходу із термінальної сесії. Для цього можна скористатися командою nohup. Ця команда дозволяє запустити програму, блокуючи сигнали SIGHUP , що надсилаються процесу. В результаті процес буде виконуватися навіть при виході з терміналу, в якому його було запущено.

Застосуємо цю методику під час запуску нашого скрипта:

Nohup ./myscript &
Ось що буде виведено до терміналу.


Команда nohup

Команда nohup відв'язує процес від терміналу. Це означає, що процес втратить посилання на STDOUT та STDERR . Для того, щоб не втратити дані, що виводяться скриптом, nohup автоматично перенаправляє повідомлення, що надходять у STDOUT і STDERR, у файл nohup.out .

Зверніть увагу на те, що при запуску декількох скриптів з однієї і тієї ж директорії те, що вони виводять, потрапить в один файл nohup.out.

Перегляд завдань

Команда jobs дозволяє переглядати поточні завдання, що виконуються в оболонці. Напишемо такий скрипт:

#!/bin/bash count=1 while [ $count -le 10 ] do echo "Loop #$count" sleep 10 count=$(($count + 1)) done
Запустимо його:

$./myscript
І тимчасово зупинимо комбінацією клавіш CTRL+Z.


Запуск та призупинення скрипту

Запустимо той самий скрипт у фоновому режимі, при цьому перенаправимо виведення скрипту у файл так, щоб він нічого не виводив на екрані:

$ ./myscript > outfile &
Виконавши тепер команду jobs, ми побачимо відомості як про зупинений скрипт, так і про те, який працює у фоні.


Отримання відомостей про скрипти

Ключ -l під час виклику команди jobs вказує на те, що нам потрібна інформація про ID процесів.

Перезапуск призупинених завдань

Щоб перезапустити скрипт у фоновому режимі, можна скористатися командою bg .

Запустимо скрипт:

$./myscript
Натисніть CTRL + Z , що зупинить його виконання. Виконаємо наступну команду:

$bg


Команда bg

Тепер скрипт виконується у фоновому режимі.

Якщо у вас є кілька призупинених завдань, для перезапуску конкретного завдання команді bg можна передати його номер.

Для перезапуску завдання в звичайному режиміскористайтесь командою fg:

Планування запуску скриптів

Linux надає пару способів запуску bash-скриптів у заданий час. Це команда at та планувальник завдань cron.

Виклик команди at виглядає так:

At [-f filename] time
Ця команда розпізнає безліч форматів часу.

  • Стандартний, із зазначенням годин та хвилин, наприклад – 10:15.
  • З використанням індикаторів AM/PM до або після полудня, наприклад - 10:15PM.
  • З використанням спеціальних імен, таких, як now, noon, midnight.
На додаток до можливості вказівки часу запуску завдання, команді at можна передати і дату, використовуючи один із форматів, що підтримуються їй.
  • Стандартний формат вказівки дати, коли дата записується за шаблонами MMDDYY , MM/DD/YY , або DD.MM.YY .
  • Текстове подання дати, наприклад, Jul 4 або Dec 25, при цьому рік можна вказати, а можна обійтися і без нього.
  • Запис виду now + 25 minutes.
  • Запис вигляду 10:15PM tomorrow.
  • Запис вигляду 10:15 + 7 days.
Не заглиблюватимемося в цю тему, розглянемо простий варіант використання команди:

$ at -f ./myscript now


Планування завдань з використанням команди at

Ключ -M при виклику at використовується для відправки того, що виведе скрипт, електронній поштіякщо система відповідним чином налаштована. Якщо відправлення електронного листанеможлива, цей ключ просто придушить висновок.

Для того щоб переглянути список завдань, що чекають на виконання, можна скористатися командою atq:


Список завдань, що очікують виконання

Видалення завдань, що очікують виконання

Видалити завдання, яке очікує на виконання, дозволяє команда atrm . Під час її виклику вказують номер завдання:

$ atrm 18


Видалення завдання

Запуск скриптів за розкладом

Планування одноразового запуску скриптів з використанням команди at здатне полегшити життя в багатьох ситуаціях. Але як бути, якщо потрібно, щоб скрипт виконувався в той самий час щодня, або раз на тиждень, або раз на місяць?

У Linux є утиліта crontab, що дозволяє планувати запуск скриптів, які потрібно виконувати регулярно.

Crontab виконується у фоні і, ґрунтуючись на даних у так званих cron-таблицях, запускає завдання за розкладом.

Щоб переглянути існуючу таблицю завдань cron , скористайтеся такою командою:

$ crontab -l
При плануванні запуску скрипту за розкладом crontab приймає дані про те, коли потрібно виконати завдання у такому форматі:

Хвилина, година, день місяця, місяць, день тижня.
Наприклад, якщо треба, щоб якийсь скрипт з ім'ям command виконувався щодня о 10:30, цьому відповідатиме такий запис у таблиці завдань:

30 10 * * * command
Тут універсальний символ *, використаний для полів, що задають день місяця, місяць і день тижня, вказує на те, що cron повинен виконувати команду щодня кожного місяця о 10:30.

Якщо, наприклад, треба, щоб скрипт запускався о 4:30PM щопонеділка, знадобиться створити в таблиці завдань такий запис:

30 16 * * 1 command
Нумерація днів тижня починається з 0,0 означає неділю, 6 – суботу. Ось ще один приклад. Тут команда виконуватиметься о 12 годині дня в перший день кожного місяця.

00 12 1 * * command
Нумерація місяців починається з першого.
Щоб додати запис до таблиці, потрібно викликати crontab з ключем -e:

Crontab -e
Потім можна вводити команди формування розкладу:

30 10 * * * /home/likegeeks/Desktop/myscript
Завдяки цій команді скрипт буде викликатись щодня о 10:30. Якщо ви зіткнетеся з помилкою «Resource temporarily unavailable», виконайте наведену нижче команду з правами root-користувача:

$ rm -f /var/run/crond.pid
Організувати періодичний запуск скриптів з використанням cron можна ще простіше, скориставшись кількома спеціальними директоріями:

/etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
Якщо помістити файл скрипта в одну з них, це призведе відповідно до його щогодинного, щоденного, щотижневого або щомісячного запуску.

Запуск скриптів при вході в систему та при запуску оболонки

Автоматизувати запуск скриптів можна, спираючись на різні події, такі як вхід користувача до системи або запуск оболонки. можна почитати про файли, що обробляються у подібних ситуаціях. Наприклад, це такі файли:

$HOME/.bash_profile $HOME/.bash_login $HOME/.profile
Щоб запускати скрипт під час входу до системи, помістіть його виклик у файл.bash_profile .

А як щодо запуску скриптів під час відкриття терміналу? Організувати це допоможе файл.bashrc.

Підсумки

Сьогодні ми розібрали питання щодо управління життєвим цикломсценаріїв, поговорили про те, як запускати скрипти на тлі, як планувати їх виконання за розкладом. Наступного разу читайте про функції в bash-скриптах та розробку бібліотек.

Шановні читачі! А ви використовуєте засоби планування запуску сценаріїв командного рядка за розкладом? Якщо так – розкажіть будь ласка про них.



Розповісти друзям