Онлайн робочі станції OnWorks Linux та Windows

логотип

Безкоштовний онлайн-хостинг для робочих станцій

<Попередній | зміст | Наступна>

Пастки

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

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

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

пастка сигнал аргументу [сигналізувати...]

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

Ось простий приклад:



#! / бін / баш


# trap-demo: проста демонстрація обробки сигналів

#! / бін / баш


# trap-demo: проста демонстрація обробки сигналів


trap "echo 'Я ігнорую вас'." SIGINT SIGTERM for i в {1..5}; робити

echo "Ітерація $i з 5" сон 5

зроблений

trap "echo 'Я ігнорую вас'." SIGINT SIGTERM for i в {1..5}; робити

echo "Ітерація $i з 5" сон 5

зроблений


Цей сценарій визначає пастку, яка буде виконувати нудьгувати команду кожного разу, коли сигнал SIG-INT або SIGTERM отримується під час виконання сценарію. Виконання програми виглядає так, коли користувач намагається зупинити скрипт, натиснувши кнопку Ctrl-c:


[me@linuxbox ~]$ пастка-демо

Ітерація 1 з 5

Ітерація 2 з 5 Я вас ігнорую. Ітерація 3 з 5 Я вас ігнорую. Ітерація 4 з 5

Ітерація 5 з 5

[me@linuxbox ~]$ пастка-демо

Ітерація 1 з 5

Ітерація 2 з 5 Я вас ігнорую. Ітерація 3 з 5 Я вас ігнорую. Ітерація 4 з 5

Ітерація 5 з 5


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

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



#! / бін / баш

# trap-demo2: проста демонстрація обробки сигналу exit_on_signal_SIGINT () {

echo "Сценарій перервано." 2>&1 вихід 0

}


exit_on_signal_SIGTERM () {

echo "Сценарій завершено." 2>&1 вихід 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM

#! / бін / баш

# trap-demo2: проста демонстрація обробки сигналу exit_on_signal_SIGINT () {

echo "Сценарій перервано." 2>&1 вихід 0

}


exit_on_signal_SIGTERM () {

echo "Сценарій завершено." 2>&1 вихід 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM



для i в {1..5}; робити

echo "Ітерація $i з 5" сон 5

зроблений


для i в {1..5}; робити

echo "Ітерація $i з 5" сон 5

зроблений


Цей сценарій містить два пастка команди, по одній для кожного сигналу. Кожна пастка, у свою чергу, визначає функцію оболонки, яка має виконуватися при отриманні конкретного сигналу. Зверніть увагу на включення an вихід команди в кожній із функцій обробки сигналів. Без вихід, сценарій продовжиться після завершення функції.

Коли користувач натискає Ctrl-c під час виконання цього скрипту результати виглядають так:



[me@linuxbox ~]$ trap-demo2

Ітерація 1 з 5

Ітерація 2 з 5 Сценарій перервано.

[me@linuxbox ~]$ trap-demo2

Ітерація 1 з 5

Ітерація 2 з 5 Сценарій перервано.


зображення

Тимчасові файли

Однією з причин, по якій обробники сигналів включаються в сценарії, є видалення тимчасових файлів, які сценарій може створити для зберігання проміжних результатів під час виконання. Іменувати тимчасові файли – це своєрідне мистецтво. Традиційно програми на Unix-подібних системах створюють свої тимчасові файли в / Tmp каталог, спільний каталог, призначений для таких файлів. Однак, оскільки каталог є спільним, це створює певні проблеми з безпекою, особливо для програм, що працюють з привілеями суперкористувача. Крім очевидного кроку встановлення належних дозволів для файлів, доступних для всіх користувачів системи, важливо надати тимчасовим файлам непередбачувані імена файлів. Це дозволяє уникнути експлойту, відомого як a тимчасова гонка атака. Один із способів створити непередбачувану (але все одно описову) назву - це зробити щось на кшталт цього:

tempfile=/tmp/$(базова назва $0).$$.$RANDOM

Це створить ім’я файлу, яке складається з назви програми, за яким слідує її ідентифікатор процесу (PID), за яким слідує випадкове ціле число. Зауважте, однак, що $RAN- DOM Змінна оболонки повертає лише значення в діапазоні 1-32767, що не є дуже великим діапазоном з точки зору комп'ютера, тому одного екземпляра змінної недостатньо для подолання рішучого зловмисника.



зображення

Кращий спосіб - використовувати mktemp програма (не плутати з mktemp функція стандартної бібліотеки), щоб і назвати, і створити тимчасовий файл. The mk- темп програма приймає шаблон як аргумент, який використовується для побудови імені файлу. Шаблон повинен містити серію символів «X», які замінюються відповідною кількістю випадкових літер і цифр. Чим довший ряд символів «X», тим довший ряд випадкових символів. Ось приклад:

tempfile=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)

Це створює тимчасовий файл і присвоює його ім’я змінній тимчасовий файл. Символи «X» у шаблоні замінюються випадковими літерами та цифрами, щоб остаточне ім'я файлу (яке в цьому прикладі також включає розгорнуте значення спеціального параметра $$ щоб отримати PID) може бути приблизно таким:

/tmp/foobar.6593.UOZuvM6654

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

[[ -d $HOME/tmp ]] || mkdir $HOME/tmp


Найпопулярніші хмарні обчислення ОС на OnWorks: