Unix / Linux - Сигналы и ловушки

Здравствуйте, будущие компьютерные маги! Сегодня мы погружаемся в fascинирующий мир сигналов и ловушек Unix/Linux. Не волнуйтесь, если вы новички в программировании - я буду вести вас через это приключение шаг за шагом, как я делал это для countless студентов на протяжении многих лет преподавания. Так что отправляемся в это захватывающее путешествие вместе!

Unix / Linux - Signals and Traps

Что такое сигналы?

Представьте, что вы находитесь на оживленной кухне ресторана. Шеф-повар (давайте назовем его Шеф Unix) должен быстро communicate с своим персоналом. Вместо того чтобы кричать через шум, он использует систему жестикуляции. Это pretty much то, что сигналы в мире Unix/Linux - способ для процессов быстро и эффективно общаться.

Сигналы - это программные прерывания, отправляемые в программу для indicate, что произошло важное событие. Эти события могут варьироваться от запросов пользователя до exceptional runtime occurrences.

Список сигналов

Точно так же, как Шеф Unix может иметь разные жестикуляции для "больше соли", "торопись" или "возьми перерыв", системы Unix/Linux имеют variety сигналов для разных целей. Давайте посмотрим на некоторые из самых распространенных:

Signal Name Signal Number Description
SIGHUP 1 Hangup detected on controlling terminal or death of controlling process
SIGINT 2 Interrupt from keyboard (Ctrl+C)
SIGQUIT 3 Quit from keyboard (Ctrl+)
SIGKILL 9 Kill signal (cannot be caught or ignored)
SIGTERM 15 Termination signal
SIGSTOP 17, 19, 23 Stop the process (cannot be caught or ignored)

Условия по умолчанию

Когда сигнал отправляется в процесс, процесс примет действие по умолчанию,除非另有指示. Эти действия по умолчанию похожи на инстинктивные реакции нашего кухонного персонала. Например:

  1. Завершить процесс
  2. Игнорировать сигнал
  3. Создать дамп памяти
  4. Остановить процесс
  5. Продолжить остановленный процесс

Отправка сигналов

Теперь давайте узнаем, как отправлять эти сигналы. В Unix/Linux мы используем команду kill для отправки сигналов процессам. Не позволяйте названию ввести вас в заблуждение - kill не всегда завершает процессы; это просто способ отправки сигналов.

Вот как можно использовать команду:

kill -signal_name process_id

Например, чтобы отправить сигнал SIGTERM процессу с идентификатором 1234:

kill -SIGTERM 1234

Или, используя номер сигнала:

kill -15 1234

Ловля сигналов

Что, если бы наш кухонный персонал мог решать, как реагировать на сигналы Шефа Unix, вместо того чтобы всегда следовать default реакции? Это то, что позволяет ловля сигналов в программировании.

В скриптах shell мы используем команду trap для перехвата сигналов и указания, что делать при их получении. Вот базовая синтаксис:

trap command signal(s)

Давайте рассмотрим пример:

#!/bin/bash

trap "echo Bonjour!" SIGINT SIGTERM

echo "It's a trap!"
while true
do
sleep 60
done

В этом скрипте, если он получит SIGINT или SIGTERM, он выведет "Bonjour!" вместо завершения. Это как сказать нашему кухонному персоналу: "Когда шеф сигнализирует о остановке, скажи 'Bonjour!' вместо того чтобы действительно останавливаться."

Удаление временных файлов

Одно из common применений ловушек - это清理 временных файлов перед выходом из скрипта. Вот пример:

#!/bin/bash

# Создать временный файл
temp_file=$(mktemp)

# Настроить ловушку для удаления временного файла при выходе
trap "rm -f $temp_file" EXIT

# Использовать временный файл
echo "Hello, World!" > $temp_file
cat $temp_file

# Временный файл будет автоматически удален при выходе из скрипта

Этот скрипт создает временный файл, записывает в него, читает из него, а затем автоматически удаляет его при выходе из скрипта, благодаря ловушке.

Игнорирование сигналов

Иногда вы можете захотеть игнорировать определенные сигналы. В нашей аналогии с кухней это было бы как сказать шефу: "Несмотря на то, сколько раз ты сигнализируешь о добавлении больше соли, я не буду добавлять больше!"

Вот как можно игнорировать сигнал:

trap "" SIGINT

Это tells скрипту не делать ничего при получении сигнала SIGINT.

Сброс ловушек

Что, если вы хотите вернуться к default поведению после ловли сигнала? Вы можете сбросить ловушку следующим образом:

trap - SIGINT

Это удаляет ловушку для SIGINT, возвращаясь к default поведению.

Вот более complete пример:

#!/bin/bash

# Изначально, ловить SIGINT
trap "echo You can't stop me!" SIGINT

echo "Try to stop me with Ctrl+C..."
sleep 10

# Теперь, сбросить ловушку
trap - SIGINT

echo "Okay, now you can stop me with Ctrl+C..."
sleep 10

echo "If you see this, you didn't stop me!"

Этот скрипт сначала ловит SIGINT, а затем сбрасывает ловушку через 10 секунд. Это как сказать нашему кухонному персоналу: "Игнорируйте сигнал остановки на 10 секунд, а затем вернитесь к normal."

И вот оно, друзья! Мы прошли через страну Unix/Linux сигналов и ловушек. Помните, что практика делает perfect. Попробуйте писать свои собственные скрипты, экспериментируйте с разными сигналами, и вскоре вы сможете conduct свою own оркестр процессов, как настоящий maestro. Счастливого кодирования!

Credits: Image by storyset