程這一層)
授權(quán)與合規(guī)聲明本文全部操作對象均為自建隔離靶場本機(jī)容器或隔離虛擬機(jī)涉及安全測試的環(huán)節(jié)必須以取得合法授權(quán)為前提。未經(jīng)授權(quán)的滲透測試違反《中華人民共和國網(wǎng)絡(luò)安全法》與《刑法》相關(guān)條款須承擔(dān)相應(yīng)法律責(zé)任。本文只講環(huán)境配置、版本對照與靶場隔離不含任何攻擊步驟、利用載荷與繞過手法請勿將文中環(huán)境指向任何非自有系統(tǒng)。一、一條命令停不下來先分清是哪一件事1.1 事情往往是這樣開始的你敲了一條命令屏幕上開始往外滾東西或者干脆什么都不動只有光標(biāo)在那兒等著。你覺得不對勁按下了中斷組合鍵。有時候一次就回來了提示符重新出現(xiàn)有時候你按了三四次屏幕還是老樣子。更讓人迷惑的是同一條命令、同一個終端昨天按一次就回來今天怎么按都沒用。還有另一種情形你直接關(guān)掉終端窗口以為事情就這樣結(jié)束了。過了一會兒新開一個終端去看發(fā)現(xiàn)之前那個東西還在跑。這幾種現(xiàn)象嘴上說的都是停不下來可它們落在不同的位置上。第一種是你發(fā)出的信號到底給了誰、對方有沒有理它第二種是發(fā)信號的那個源頭終端走了之后作業(yè)被怎么處置。本文講的是前一層信號與前臺進(jìn)程。1.2 分流只需要三個問題分流不需要復(fù)雜工具三個問題就夠。第一個問題按鍵之后命令本身有沒有變化如果它停了說明信號送到了而且被當(dāng)成了要處理的事如果它毫無反應(yīng)那要問的就是——信號沒送到它手里還是它收到了卻選擇不理。這兩個原因的解釋完全不同。第二個問題你按了幾次一次就回來和按好幾次才有反應(yīng)看起來是兩個毛病其實(shí)是同一件事的兩面。原因在第三章和第四章。第三個問題終端窗口是不是被你關(guān)掉了如果是那走的根本不是按鍵這條路而是第五章要講的另一條路。這三個問題各自對應(yīng)一個只讀動作。??代碼待驗(yàn)證ps# 只讀看當(dāng)前這個會話下有哪些進(jìn)程dockerps# 只讀看容器列表以及它們各自當(dāng)前的狀態(tài)兩條都只做看這一件事不啟動、不停止、也不改任何配置。你看到的現(xiàn)象更可能落在哪一層本文的哪一章按鍵之后命令停了提示符回來了信號送到了而且被當(dāng)成要處理的事第三章、第四章按了好幾次命令還在跑信號到了但接收方自己接管了它第四章關(guān)掉終端之后它居然還在跑終端退出與作業(yè)被如何處理第五章容器停不下來過幾秒才停容器的停止信號與寬限期第六章1.3 本文只講控制層先把范圍說清楚。本文的觀察對象是控制層你怎么把一件事停下來以及停下來這個動作到底發(fā)給了誰。有幾件事本文不寫不寫怎么強(qiáng)行終止別人的進(jìn)程不寫進(jìn)程注入這一類話題也不展開容器的資源限制與內(nèi)存那一層。文中出現(xiàn)的每一條命令都只做看這件事。二、中斷組合鍵發(fā)出的是哪個信號2.1 一個鍵一個信號按下中斷組合鍵之后終端做的事不是把那條命令關(guān)掉而是發(fā)出一個信號。這一點(diǎn)是所有后續(xù)討論的前提按鍵本身不等于停止按鍵只是把一封信寄出去。這封信叫什么名字官方手冊寫得很直接。Bash 官方手冊在講信號的那一節(jié)里描述這個信號來源時用的措辭是usually generated by ^C——也就是說中斷組合鍵產(chǎn)出的信號就是SIGINT。那么停下來這個動作是誰做的是收到信號的那個進(jìn)程自己做的。信號到了它手上它可以按默認(rèn)方式對待對SIGINT來說默認(rèn)就是終止自己也可以自己接管、決定不終止。所以按了鍵和停下來了之間從來不是等號。2.2 shell 自己對這些信號的態(tài)度還有一個容易被忽略的角色shell 本身。你在終端上敲的那個鍵最終是終端把信號發(fā)給了一批進(jìn)程而 shell 在不在這批進(jìn)程里取決于下一章要講的進(jìn)程組歸屬。同時shell 收到某些信號時也有自己的默認(rèn)態(tài)度。官方原話是逐字引用When Bash is interactive, in the absence of any traps, it ignores SIGTERM (so that ‘kill 0’ does not kill an interactive shell), and catches and handles SIGINT (so that the wait builtin is interruptible). When Bash receives a SIGINT, it breaks out of any executing loops. In all cases, Bash ignores SIGQUIT.這段話里含三件事逐條拆開看第一交互式 shell 忽略SIGTERM你在終端里沖著這個 shell 發(fā)SIGTERM它不會因此退出官方還給這條設(shè)計配了理由——為了不讓kill 0把交互式 shell 干掉。第二交互式 shell 會接住并處理SIGINT目的是讓wait這個內(nèi)建命令可以被中斷它收到SIGINT之后會跳出正在執(zhí)行的循環(huán)。第三在任何情況下Bash 都忽略SIGQUIT。官方用的是In all cases沒有留例外。截至 2026-09-27官方手冊這一節(jié)對交互式 shell 的口徑就是上面這三句。信號名交互式 Bash 的默認(rèn)態(tài)度官方依據(jù)逐字要點(diǎn)本文位置SIGTERM忽略it ignores SIGTERM (so that kill 0 does not kill an interactive shell)本章SIGINT接住并處理收到后跳出正在執(zhí)行的循環(huán)catches and handles SIGINT (so that the wait builtin is interruptible)本章SIGQUIT在任何情況下都忽略In all cases, Bash ignores SIGQUIT.本章SIGHUP默認(rèn)退出The shell exits by default upon receipt of a SIGHUP.第五章2.3 信號名從哪里來信號是一組帶名字的東西kill -l這個動作的作用就是把信號名列出來。本文只把它是一個列出信號名的動作這件事放在這里不貼它列出的內(nèi)容——本批一律不貼終端里的原始輸出。??代碼待驗(yàn)證kill-l# 只讀列出信號名不發(fā)送任何信號也不改變?nèi)魏螙|西有一點(diǎn)要單獨(dú)說清楚kill -l只是看名字它自己不發(fā)信號、不結(jié)束任何進(jìn)程。名字和編號的對應(yīng)關(guān)系請以你自己系統(tǒng)上的手冊為準(zhǔn)本文不列任何編號對照表討論范圍只涉及五個名字SIGINT、SIGTERM、SIGKILL、SIGQUIT、SIGHUP。三、鍵盤信號到底發(fā)給了誰3.1 未啟用作業(yè)控制同一個進(jìn)程組這是全文最硬的一條也是為什么有時按一下就回來了、有時按好幾次也沒用的根子。官方原話逐字引用the shell receives keyboard-generated signals such as SIGINT (usually generated by ‘^C’) that users commonly intend to send to that command. This happens because the shell and the command are in the same process group as the terminal, and ‘^C’ sends SIGINT to all processes in that process group.把這段翻成要點(diǎn)是三層意思第一你在終端里按下中斷鍵時這個信號的收件人不是你以為的那一個進(jìn)程而是終端那個進(jìn)程組里的所有進(jìn)程。第二之所以這件事會順帶打到 shell 身上是因?yàn)槲磫⒂米鳂I(yè)控制時shell 和它正在跑的那條命令處在同一個進(jìn)程組里——也就是與終端相關(guān)聯(lián)的那個進(jìn)程組。第三官方對這句話的用途也說得很明白用戶的本意是把這個信號發(fā)給那條命令但因?yàn)閮烧咄Mshell 也跟著收到了。這解釋了一個很日常的現(xiàn)象——你按中斷鍵的時候那條命令停了命令行會話有時候也會跟著頓一下。3.2 啟用作業(yè)控制shell 不在那個進(jìn)程組里那么為什么有時候感覺又不一樣了因?yàn)?shell 到底在不在那個進(jìn)程組里是會變的。官方對另一種情形的表述是逐字引用the shell does not receive keyboard-generated signals, because it is not in the same process group as the terminal.啟用作業(yè)控制之后shell 把自己移出了與終端關(guān)聯(lián)的那個進(jìn)程組于是鍵盤產(chǎn)生的信號打不到它身上。信號還是照發(fā)只是那份收件名單里沒有它了。兩種情形并排看就是下面這張表情形shell 在不在終端那個進(jìn)程組里鍵盤信號發(fā)給誰shell 會不會收到未啟用作業(yè)控制在該進(jìn)程組里的所有進(jìn)程會收到啟用作業(yè)控制不在該進(jìn)程組里的進(jìn)程不含 shell不會收到這張表解決了本文開頭那個困惑的前一半你按下的每一次信號都發(fā)出去了但到底有幾方收到取決于當(dāng)時誰和誰在同一個組里。3.3 為什么這件事對排障有用這一章的價值不在于記住進(jìn)程組這個詞而在于改掉一個默認(rèn)假設(shè)你在終端里按鍵不是你直接對那條命令說話而是往一個組里廣播了一封信誰收到、誰理它是接收方自己的選擇。所以當(dāng)你發(fā)現(xiàn)我按了它沒停的時候第一條判斷不是我按得不夠用力而是這封信到了它手上沒有以及它收到之后做了什么。后半個問題就是下一章。??代碼待驗(yàn)證ps# 只讀看當(dāng)前會話下有哪些進(jìn)程以及它們各自的歸屬信息本文不給怎么改進(jìn)程組歸屬的示范動作——那屬于改環(huán)境的操作不是看。四、命令結(jié)束之后shell 的兩條判斷4.1 未啟用作業(yè)控制時shell 還要再判一次前兩章講了未啟用作業(yè)控制時shell 和命令在同一個組里所以 shell 自己也收到了那個信號。既然收到了shell 該怎么做官方說它會等前臺命令先結(jié)束然后做判斷判斷的依據(jù)是這條命令是怎么結(jié)束的。于是就有了兩條路。第一條路命令確實(shí)是因?yàn)檫@個信號而結(jié)束的。官方原話逐字引用If the command terminates due to the SIGINT, Bash concludes that the user meant to send the SIGINT to the shell as well, and acts on the SIGINT意思是既然命令是被SIGINT終止的Bash 就認(rèn)為你本來也想讓 shell 收到這個信號。走這一條路你按一次鍵命令停了shell 也按收到SIGINT的方式動作——所以提示符干脆地回來了。第二條路命令不是因?yàn)檫@個信號而結(jié)束的。官方原話逐字引用If the command does not terminate due to SIGINT, the program handled the SIGINT itself and did not treat it as a fatal signal. In that case, Bash does not treat SIGINT as a fatal signal, either…意思是如果命令沒被這個信號干掉那就說明這個程序自己接管了這個信號并且不把它當(dāng)成會要命的信號。這種情況下Bash 也不把它當(dāng)成會要命的信號。官方在這里舉了一個很具體的例子編輯器會把SIGINT當(dāng)成一個普通操作來處理比如中止一條正在進(jìn)行的編輯命令而不是退出程序本身。4.2 這就解釋了按了沒用把這兩條路放在一起那個困惑就解開了。你按下中斷鍵信號發(fā)到了整個進(jìn)程組里前臺那個程序收到了。接下來往哪條路走取決于這個程序自己愿不愿意停它愿意停命令結(jié)束Bash 判定你也想讓 shell 停shell 跟著一起動作它自己接管了這個信號、并且不認(rèn)為這個信號要命它就會繼續(xù)跑Bash 也跟著不把它當(dāng)回事。所以按好幾次才有反應(yīng)這件事多數(shù)時候不是信號沒送到而是接收方每一次都選擇了自己處理。你按多少次它就自己處理多少次只有當(dāng)它處理到某個邊界、真的退出了這個循環(huán)才結(jié)束。還要補(bǔ)一個前提這條判斷是未啟用作業(yè)控制時的邏輯。啟用作業(yè)控制時shell 根本不在那個組里、收不到鍵盤信號也就談不上跟著一起停。命令結(jié)束的方式Bash 的判斷你看到的結(jié)果命令因該信號而結(jié)束認(rèn)為你也想把這個信號發(fā)給 shell并且照做命令停shell 也跟著動作命令沒因該信號結(jié)束程序自己處理了它不把這個信號當(dāng)成會要命的信號命令繼續(xù)跑看起來像按了沒用??代碼待驗(yàn)證信號送到了 和 對方停下來了 是兩件事判斷順序是 1. 這個信號發(fā)出去了嗎——按鍵這個動作本身就發(fā)出去了。 2. 誰收到了——取決于當(dāng)時誰和誰在同一個進(jìn)程組里第三章。 3. 收到的人怎么處理它——它自己說了算這就是本章的兩條分岔。五、關(guān)掉終端窗口之后SIGHUP 與 disown5.1 shell 收到 SIGHUP 就退出前面幾章講的是按鍵這條路。還有一條路是終端本身沒了你關(guān)掉終端窗口或者連接斷開了。官方對 shell 在這種情況下的行為寫得很明確逐字引用The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped.兩句話兩個要點(diǎn)。第一shell 收到SIGHUP時默認(rèn)行為就是退出。第二也是最容易讓人意外的一點(diǎn)在退出之前交互式 shell 會把這個SIGHUP再發(fā)一遍給它手上的所有作業(yè)不管這些作業(yè)是正在運(yùn)行的還是已經(jīng)停下的。也就是說關(guān)掉終端這件事不是只管 shell 自己它會順手把信號轉(zhuǎn)發(fā)出去。這一條正好解釋了本文開頭那個現(xiàn)象。你以為關(guān)掉窗口就等于結(jié)束了其實(shí)這條鏈?zhǔn)沁@樣的終端沒了 → shell 收到SIGHUP→ shell 決定退出 → 退出之前先把SIGHUP轉(zhuǎn)發(fā)給它帶著的那些作業(yè)。至于每個作業(yè)收到之后停不停仍然回到第四章那個問題——它自己怎么處理這個信號。5.2 讓某個作業(yè)不收到它既然默認(rèn)是轉(zhuǎn)發(fā)給所有作業(yè)那自然會有一個反過來的需求我不想讓某個作業(yè)收到這封信。官方給的答案是disown——把這個作業(yè)從作業(yè)表里移出它就不會被轉(zhuǎn)發(fā)到了。這里要分清的是disown處理的是要不要把它算在我的作業(yè)里這件事而不是給它發(fā)一個停止信號。它本身不是一種停下來的動作它改變的是一份名單。5.3 交互式 shell 對 SIGTERM 與 SIGQUIT回到第二章那張表把兩種外來信號再對一次交互式 shell忽略SIGTERM理由是為了不讓kill 0把交互式 shell 干掉并且在任何情況下都忽略SIGQUIT。這兩條合起來能回答一個常見的疑問“我在終端里沖著 shell 發(fā)一個終止信號它怎么不退出”——因?yàn)檫@是它有意為之的默認(rèn)態(tài)度不是它壞了。要讓它走走的是另一條路終端退出帶來的SIGHUP。情形默認(rèn)行為官方依據(jù)逐字要點(diǎn)交互式 shell 收到SIGTERM忽略it ignores SIGTERM (so that kill 0 does not kill an interactive shell)交互式 shell 收到SIGQUIT在任何情況下都忽略In all cases, Bash ignores SIGQUIT.交互式 shell 收到SIGINT接住并處理catches and handles SIGINT交互式 shell 收到SIGHUP默認(rèn)退出退出前把SIGHUP轉(zhuǎn)發(fā)給所有作業(yè)運(yùn)行中的與已停止的The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped.想讓某個作業(yè)不被轉(zhuǎn)發(fā)到用disown把它從作業(yè)表里移出同上下面這份資料把信號發(fā)給誰、誰理它、終端退出之后作業(yè)怎么辦這三段整理成了一頁和本章的對照表呼應(yīng)配套資料把信號歸屬、兩條判定、終端退出整理成一頁對照表放在資料包里掃碼即可獲取六、容器這一側(cè)docker stop 之后為什么要等幾秒6.1 默認(rèn)先 SIGTERM寬限期后才 SIGKILL前五章講的是你在終端里跑東西。容器里的程序是另一套入口但問的是同一個問題停下來這個動作到底發(fā)給了誰、發(fā)的是什么。Docker CLI 對docker container stop的說明是逐字引用The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL. The first signal can be changed with the STOPSIGNAL instruction in the container’s Dockerfile, or the --stop-signal option to docker run and docker create.拆成三層看第一先發(fā)給容器里的主進(jìn)程一個SIGTERM。注意是主進(jìn)程——容器里往往有好幾個進(jìn)程在跑先收到這封信的是被指定為主進(jìn)程的那一個。第二寬限期過去之后再發(fā)SIGKILL。官方在另一句里把這件事說得更直逐字引用If the container does not exit after the timeout elapses, it’s forcibly killed with a SIGKILL signal.也就是說寬限期是給它一個自己收尾的機(jī)會這個機(jī)會用完了它還沒退才走強(qiáng)制結(jié)束那一手。這就回答了本文開頭那個問題docker stop之后為什么要等幾秒——那幾秒不是命令卡了而是它本來就在等等主進(jìn)程自己把收尾做完。第三第一封信的名字是可以換的換的地方有兩個鏡像里的STOPSIGNAL或者啟動時的--stop-signal選項(xiàng)。6.2 默認(rèn)是幾秒以及這個數(shù)到底從哪來關(guān)鍵的一句在這里逐字引用If no default is configured for the container, the Daemon determines the default, and is 10 seconds for Linux containers, and 30 seconds for Windows containers.這句話里有一個極容易被略過去的條件“如果沒有為容器配置默認(rèn)值”。也就是說這個數(shù)不是容器自己帶來的而是在容器沒有自帶配置的時候由守護(hù)進(jìn)程來決定。截至 2026-09-27官方這一頁給出的守護(hù)進(jìn)程口徑是Linux 容器 10 秒Windows 容器 30 秒。為什么要強(qiáng)調(diào)默認(rèn)值從哪來因?yàn)樗苯記Q定排障的下一步。你看到等了十來秒才停不一定說明這條命令寫死了 10 秒而可能是這個容器沒有自己的配置、落到了守護(hù)進(jìn)程的默認(rèn)上。要確認(rèn)走的是哪一條默認(rèn)就得看容器本身有沒有配過。6.3 信號與寬限期怎么改官方對這兩個開關(guān)的說明是逐字引用--signalSignal to send to the container--timeout/-tSeconds to wait before killing the container兩條合起來就是這一章的全部機(jī)制一個開關(guān)決定第一封信叫什么名字另一個開關(guān)決定等多久。寬限期這個數(shù)由超時參數(shù)給出官方在這一頁寫作--timeout簡寫-t在不同入口下它也可能寫作--stop-timeout具體以你所用入口的文檔為準(zhǔn)。而等多久還有一個特殊取值逐字引用If you set --timeout to -1, no timeout is applied, and the daemon waits indefinitely for the container to exit.設(shè)成-1就是不設(shè)時限守護(hù)進(jìn)程會一直等下去等到容器自己退出為止。這一條用的時候要留意它不是一個更快停下來的設(shè)置而是一個不再走強(qiáng)制那一手、愿意一直等下去的設(shè)置。你觀察到的現(xiàn)象對應(yīng)的機(jī)制官方依據(jù)逐字要點(diǎn)docker stop之后等了幾秒才停寬限期到了才走強(qiáng)制結(jié)束after a grace period, SIGKILL等待的時間大約是十來秒Linux 容器容器沒配默認(rèn)值由守護(hù)進(jìn)程決定If no default is configured for the container, the Daemon determines the default想換第一封信的名字鏡像的STOPSIGNAL或--stop-signalcan be changed with the STOPSIGNAL instruction ... or the --stop-signal option想改等待時長寬限期參數(shù)--timeout/-tSeconds to wait before killing the container想不設(shè)時限、一直等把超時設(shè)為-1no timeout is applied, and the daemon waits indefinitely6.4 只讀地看一眼容器現(xiàn)在是什么狀態(tài)??代碼待驗(yàn)證dockerps# 只讀看容器列表與當(dāng)前狀態(tài)dockerinspect容器名# 只讀看這個容器自身的配置里有沒有覆蓋默認(rèn)值docker inspect在這里的用處就是回答 6.2 那個問題這個容器的默認(rèn)值是不是沒配。沒配時間就來自守護(hù)進(jìn)程配過就是配置里寫的那一條。本文不給停止容器的示范動作——這里只講停下來這個動作的語義。七、把這一層變成動作7.1 三個只讀動作第一步先看東西還在不在。??代碼待驗(yàn)證ps# 只讀看當(dāng)前會話下還有哪些進(jìn)程dockerps# 只讀看容器列表和它們當(dāng)前的狀態(tài)這一步回答的是分流里的第一個問題。重點(diǎn)不是看它跑得好不好而是先確認(rèn)它在不在。第二步看它有沒有自己的配置。??代碼待驗(yàn)證dockerinspect容器名# 只讀看容器自身的信號與超時相關(guān)配置有沒有被改過dockerversion# 只讀確認(rèn)你在跟哪一個客戶端與守護(hù)進(jìn)程打交道第二步回答的是第六章那個默認(rèn)值從哪來的問題沒配過才是守護(hù)進(jìn)程的默認(rèn)。而docker version用來確認(rèn)你面對的是哪一個守護(hù)進(jìn)程——同一臺機(jī)器上裝了兩個環(huán)境時這一步能省掉很多繞路。7.2 現(xiàn)象到動作的對照表把前面幾章的判斷收成一張表出問題時按行對號現(xiàn)象更可能落在哪一層先做哪個只讀動作按中斷鍵命令停了信號送到了而且被當(dāng)成要處理的事看它是否已經(jīng)不在進(jìn)程列表里按了好幾次命令還在跑接收方自己接管了這個信號先確認(rèn)它是不是本來就這么設(shè)計別再重復(fù)按鍵關(guān)掉終端之后它還在終端退出與作業(yè)被如何處理看還有哪些進(jìn)程活著再考慮disown這類名單調(diào)整docker stop之后等了幾秒容器的寬限期看這個容器有沒有屬于自己的默認(rèn)值配置對 shell 發(fā)終止信號它不理交互式 shell 有意忽略SIGTERM不用重試這就是它的默認(rèn)行為這張表只需要記住一句先判斷信送到了沒有和對方理不理再決定要不要做別的動作。7.3 一頁自檢表與三條可帶走的動作出問題的時候先把下面這張自檢表過一遍檢查項(xiàng)為什么查它在哪一層我按的是哪一類鍵不同的鍵產(chǎn)出不同的信號名信號來源當(dāng)時 shell 在不在同一個進(jìn)程組里決定 shell 會不會也收到這封信進(jìn)程組歸屬命令是被告知結(jié)束的還是自己收尾的決定 shell 下一步跟不跟著停兩條判定終端是不是沒了SIGHUP走的是另一條路終端退出這個容器有沒有配過默認(rèn)值沒配過這個數(shù)就來自守護(hù)進(jìn)程容器側(cè)我想做的動作是不是強(qiáng)行結(jié)束別人不在本文范圍也不該做邊界三條可以帶走的動作先分清是沒送到還是不理會按鍵這個動作每次都會把信號發(fā)出去差別在接收方。容器側(cè)先看配置有沒有被覆蓋沒被覆蓋走的才是守護(hù)進(jìn)程的默認(rèn)。不要靠重復(fù)按鍵來解決問題重復(fù)按解決不了接收方自己的選擇。本文的使用限制所有命令均為待驗(yàn)證本文寫作環(huán)境沒有可用的 docker 環(huán)境文中每條命令都沒有實(shí)際運(yùn)行過參數(shù)寫法與默認(rèn)行為請以各自官方文檔為準(zhǔn)。本文不寫任何命令的輸出文本kill -l只作為列出信號名的動作出現(xiàn)本文不列它列出的內(nèi)容也不列任何信號編號對照表。本文不給可照抄的停止示范不寫怎么強(qiáng)制結(jié)束進(jìn)程不寫進(jìn)程組歸屬怎么改。其它層不在本文范圍容器的資源限制與內(nèi)存那一層另有專文本文只講信號與時序。把這一層的判斷順序整理成一頁放在資料里和本章的自檢表呼應(yīng)配套資料把分流、看配置、別重按三步和上面這張自檢表合成一頁放在資料包里掃碼即可獲取附表 A本文引用事實(shí)與官方出處對照表#事實(shí)照口徑一手出處 URL核驗(yàn)日期本文位置1官方原文When Bash is interactive, in the absence of any traps, it ignores SIGTERM (so that ‘kill 0’ does not kill an interactive shell), and catches and handles SIGINT (so that the wait builtin is interruptible). When Bash receives a SIGINT, it breaks out of any executing loops. In all cases, Bash ignores SIGQUIT.https://www.gnu.org/software/bash/manual/html_node/Signals.html2026-09-27第 2、5 章2官方原文the shell receives keyboard-generated signals such as SIGINT (usually generated by ‘^C’) that users commonly intend to send to that command. This happens because the shell and the command are in the same process group as the terminal, and ‘^C’ sends SIGINT to all processes in that process group.https://www.gnu.org/software/bash/manual/html_node/Signals.html2026-09-27第 3 章3官方原文the shell does not receive keyboard-generated signals, because it is not in the same process group as the terminal.https://www.gnu.org/software/bash/manual/html_node/Signals.html2026-09-27第 3 章4官方原文If the command terminates due to the SIGINT, Bash concludes that the user meant to send the SIGINT to the shell as well, and acts on the SIGINThttps://www.gnu.org/software/bash/manual/html_node/Signals.html2026-09-27第 4 章5官方原文If the command does not terminate due to SIGINT, the program handled the SIGINT itself and did not treat it as a fatal signal. In that case, Bash does not treat SIGINT as a fatal signal, either…官方在本句后舉的例子是編輯器把 SIGINT 當(dāng)作普通操作例如中止一條編輯命令https://www.gnu.org/software/bash/manual/html_node/Signals.html2026-09-27第 4 章6官方原文The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped.要讓某個作業(yè)不收到它可用 disown 把該作業(yè)從作業(yè)表里移出https://www.gnu.org/software/bash/manual/html_node/Signals.html2026-09-27第 5 章7官方原文The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL. The first signal can be changed with the STOPSIGNAL instruction in the container’s Dockerfile, or the --stop-signal option to docker run and docker create.https://docs.docker.com/reference/cli/docker/container/stop/2026-09-27第 6 章8官方原文If no default is configured for the container, the Daemon determines the default, and is 10 seconds for Linux containers, and 30 seconds for Windows containers.https://docs.docker.com/reference/cli/docker/container/stop/2026-09-27第 6 章9官方原文If the container does not exit after the timeout elapses, it’s forcibly killed with a SIGKILL signal.https://docs.docker.com/reference/cli/docker/container/stop/2026-09-27第 6 章10官方對--signal的說明Signal to send to the container對--timeout/-t的說明Seconds to wait before killing the containerhttps://docs.docker.com/reference/cli/docker/container/stop/2026-09-27第 6 章11官方原文If you set --timeout to -1, no timeout is applied, and the daemon waits indefinitely for the container to exit.https://docs.docker.com/reference/cli/docker/container/stop/2026-09-27第 6 章說明第 1–6 行取自 Bash 官方手冊 3.7.6 Signals 一節(jié)第 7–11 行取自 Docker CLI 對docker container stop的參考頁均由本批次于2026-09-27一手核驗(yàn)。本文所有命令均未實(shí)測已在正文逐處標(biāo)注代碼待驗(yàn)證本文不列任何信號編號對照表。附表 B術(shù)語速查表術(shù)語一句話解釋控制層本文的觀察對象你怎么把一件事停下來以及停下來這個動作發(fā)給了誰信號終端或 shell 發(fā)出去的一個通知按鍵不等于停止只是把通知寄出去SIGINT中斷組合鍵產(chǎn)出的那個信號官方措辭是usually generated by ^CSIGTERM容器停止時默認(rèn)先發(fā)給主進(jìn)程的那個信號交互式 shell 對它是忽略SIGKILL寬限期用完之后才發(fā)出去的那個信號屬于強(qiáng)制結(jié)束SIGQUIT交互式 Bash 在任何情況下都忽略的那個信號SIGHUPshell 收到后默認(rèn)退出的那個信號退出前會轉(zhuǎn)發(fā)給它帶的所有作業(yè)前臺命令當(dāng)前正在終端里跑、占著輸入輸出的那條命令進(jìn)程組一組進(jìn)程的集合鍵盤信號發(fā)給的是終端那個進(jìn)程組里的所有進(jìn)程作業(yè)控制啟用后 shell 會把自己移出終端那個進(jìn)程組因此收不到鍵盤信號兩條判定未啟用作業(yè)控制時shell 等前臺命令結(jié)束后做的分岔判斷寬限期容器停止時留給主進(jìn)程自己收尾的那段時間主進(jìn)程容器里被指定為主要那一個的進(jìn)程停止信號先發(fā)給它STOPSIGNAL鏡像里用來改寫第一封信叫什么名字的那條指令disown把某個作業(yè)從作業(yè)表里移出使它在 shell 退出時不被轉(zhuǎn)發(fā)到信號只讀動作本文給出的全部動作類型只看不改不啟動、不停止、不修改代碼待驗(yàn)證本文命令未在本機(jī)實(shí)測的標(biāo)記請以官方文檔為準(zhǔn)寫在最后這篇用到的資料寫這篇文章時我把 Bash 官方手冊講信號的那一節(jié)和 Docker 官方講容器停止的那一頁對照著讀了一遍。發(fā)現(xiàn)停不下來這件事官方其實(shí)拆成了三段信號發(fā)給誰、誰收到之后怎么處理、寬限期里到底在等什么。這三段散在兩份文檔里于是順手整理了幾份配套的東西靶場環(huán)境對照表DVWA、upload-labs 在 Windows / macOS / Linux 三平臺的可行性與推薦路徑Web 安全學(xué)習(xí)路線圖從基礎(chǔ)打牢到安全管理四個階段各學(xué)什么常用靶場清單每個靶場練什么、適合哪個階段資料是我自己整理的放在下面這個碼上掃碼即可獲取添加時備注「靶場」優(yōu)先通過。拿到之后建議先看環(huán)境對照表那一份先把這臺機(jī)器上還有哪些東西在等著你這件事想清楚再回頭看你的容器有沒有自己的默認(rèn)值——控制這一層的問題多數(shù)是在這里定下來的。