Unix / Linux - 信號與捕獲

你好,未來的電腦巫師們!今天,我們將深入探索Unix/Linux信號與捕獲的迷人世界。別擔心如果你是編程新手 - 我會一步步引導你走過這次冒險,就像我過去幾年來為無數學生做的那樣。所以,讓我們一起踏上這次令人興奮的旅程吧!

Unix / Linux - Signals and Traps

信號是什麼?

想像你在一個繁忙的餐廳廚房裡。廚師(我們稱他為Unix廚師)需要迅速與他的員工溝通。他不是在喧囂中大喊,而是使用一套手語信號。在Unix/Linux世界中,信號的作用與此類似 - 是進程之間快速且有效的溝通方式。

信號是發送到程序的軟件中斷,用於指示已發生重要事件。這些事件可能從用戶請求到異常運行時發生的事情。

信號列表

就像Unix廚師可能會有不同手語信號表示"多一點鹽"、"快一點"或"休息一下",Unix/Linux系統也有為不同目的而設的信號。讓我們看看一些最常見的信號:

信號名稱 信號編號 描述
SIGHUP 1 在控制終端 detect 到挂起或控制進程死亡
SIGINT 2 從鍵盤中斷(Ctrl+C)
SIGQUIT 3 從鍵盤退出(Ctrl+\)
SIGKILL 9 覆蓋信號(無法捕獲或忽略)
SIGTERM 15 終止信號
SIGSTOP 17, 19, 23 停止進程(無法捕獲或忽略)

預設動作

當信號發送到進程時,除非進程被告知 otherwise,否則進程會采取預設動作。這些預設動作就像我們廚房員工的自然反應。例如:

  1. 終止進程
  2. 忽略信號
  3. 轉儲核心
  4. 停止進程
  5. 繼續已停止的進程

發送信號

現在,讓我們學習如何發送這些信號。在Unix/Linux中,我們使用kill命令來發送信號給進程。別讓這個名字欺騙你 - kill不總是終止進程;它只是發送信號的一種方式。

這樣使用:

kill -signal_name process_id

例如,要發送SIGTERM信號給進程1234:

kill -SIGTERM 1234

或者,使用信號編號:

kill -15 1234

捕獲信號

如果我們的廚房員工能夠決定如何對Unix廚師的信號做出反應,而不是總是遵循預設反應,那會怎麼樣?這正是編程中的信號捕獲所允許的。

在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!'而不是真正停止。"

清理臨時文件

捕獲信號的一個常見用途是在腄本退出前清理臨時文件。這裡有一個例子:

#!/bin/bash

# 創建一個臨時文件
temp_file=$(mktemp)

# 設置捕獲,在退出時刪除臨時文件
trap "rm -f $temp_file" EXIT

# 使用臨時文件
echo "Hello, World!" > $temp_file
cat $temp_file

# 臨時文件將在腄本退出時自動刪除

這個腄本創建了一個臨時文件,寫入並讀取它,然後在腄本退出時自動刪除它,多虧了捕獲。

忽略信號

有時候,你可能想要忽略某些信號。在我們的廚房比喻中,這就像告訴廚師:"無論你多少次信號要多一點鹽,我都不再加了!"

這樣忽略一個信號:

trap "" SIGINT

這告訴腄本在收到SIGINT信號時不做任何事情。

重置捕獲

如果你想在捕獲信號後返回預設行為,你可以這樣重置捕獲:

trap - SIGINT

這移除了SIGINT的捕獲,返回預設行為。

這裡有一個更完整的例子:

#!/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秒內忽略停止信號,然後回到正常。"

好了,各位!我們一起穿越了Unix/Linux信號與捕獲的領地。記住,熟練才能完美。嘗試編寫你自己的腄本,玩轉不同的信號,很快你就能像真正的指揮家一樣指揮你的進程管弦樂團。祝編程愉快!

Credits: Image by storyset