TL; DR:sudo
不轉發通過的過程中sudo 1.8.11
釋放的命令的進程組since 28 May 2014 commit在發送的信號 - 蟒處理(須藤的父)和tcpdump的處理(孫)是相同的處理組中的因此sudo
不會將.terminate()
發送的SIGTERM
信號轉發到tcpdump
進程。
運行的代碼時,同時root用戶,並同時作爲一個普通用戶+ sudo的
運行作爲一個普通用戶它顯示了相同的行爲提出了對.terminate()
OSError: [Errno 1] Operation not permitted
異常(如預期)。
運行爲root
重現問題:sudo
和tcpdump
進程沒有殺害.terminate()
和代碼粘貼在.communicate()
在Ubuntu 15.10。
相同的代碼會殺死Ubuntu 12.04上的兩個進程。
tcpdump_process
名稱是誤導,因爲該變量是指sudo
進程(子進程),不tcpdump
(孫):
python
└─ sudo tcpdump -w example.pcap -i eth0 -n icmp
└─ tcpdump -w example.pcap -i eth0 -n icmp
由於@Mr.E pointed out in the comments,你不需要sudo
在這裏:你是根已經(儘管你不應該 - 你可以sniff the network without root)。如果你放棄sudo
; .terminate()
作品。
一般而言,.terminate()
不會以遞歸方式終止整個進程樹,因此預計孫子進程會存活。雖然sudo
是一個特例,from sudo(8) man page:
當運行命令爲sudo
過程的孩子,sudo
將 繼電器信號它接收到的命令。 重點是我
即sudo
應該中繼SIGTERM
到tcpdump
和tcpdump
should stop capturing packets on SIGTERM
, from tcpdump(8) man page:
tcpdump的意志,...,繼續捕獲數據包直到它被一個SIGINT信號中斷(例如,通過鍵入您的 中斷字符,通常爲control-C)或SIGTERM信號 (通常使用kill(1)命令生成)中斷爲 ;
即預期的行爲是:tcpdump_process.terminate()
發送SIGTERM到sudo
哪個中繼信號到tcpdump
應停止捕獲和兩個過程退出和返回.communicate()
tcpdump
的stderr輸出到Python腳本。
注:原則上該命令可以在沒有創建子進程,from the same sudo(8) man page運行:
作爲一個特殊的情況下,如果政策插件沒有定義密切 功能,並沒有PTY是必需的,sudo
將直接執行命令 代替調用叉(2)第一
,因此.terminate()
可以發送SIGTERM直接在tcpdump
過程 - 儘管它不是解釋:在我的測試中,在Ubuntu 12.04和15.10上創建了兩個進程。
如果我在shell中運行sudo tcpdump -w example.pcap -i eth0 -n icmp
,則kill -SIGTERM
終止這兩個進程。它看起來不像Python問題(Python 2.7.3(在Ubuntu 12.04上使用)在Ubuntu 15.10上表現相同,Python 3在這裏也失敗了)。
據處理組(job control)相關:通過preexec_fn=os.setpgrp
到subprocess.Popen()
使sudo
將在它的領導者作爲外殼使得在這種情況下tcpdump_process.terminate()
工作的新進程組(作業)。
發生了什麼事?它適用於以前的版本。
的解釋是在the sudo's source code:
做的過程中命令的發送過程不轉發信號 組,不轉發它,因爲我們不希望孩子間接殺死了 本身。例如,在某些版本的重啓 中會發生這種情況,該版本調用kill(-1,SIGTERM)來終止所有其他進程。 強調的是礦
preexec_fn=os.setpgrp
改變sudo
的處理組。 sudo
的後代如tcpdump
進程繼承了該組。 python
和tcpdump
不再處於同一個進程組中,因此.terminate()
發送的信號被sudo
中繼到tcpdump
並退出。
Ubuntu 15.04使用Sudo version 1.8.9p5
問題的代碼按原樣運行。
Ubuntu 15.10使用Sudo version 1.8.12
其中包含the commit。
sudo(8) man page in wily (15.10)仍然只談論關於孩子過程本身 - 沒有提及處理組:
作爲一個特殊的情況下,須藤將不再轉發即是由它運行 命令發出的信號。
它應該是代替:
作爲特例,須藤將不再轉發該通過的過程正在運行的命令的處理組中發送的信號。
您可以在Ubuntu's bug tracker和/或the upstream bug tracker上打開文檔問題。
如果你在做root時運行這個,爲什麼你需要調用sudo?你想做什麼? –
好的,好點。沒有'sudo'它似乎工作。但爲什麼它可以在以前的所有版本上運行? –
我不知道爲什麼,最可能的情況是,當您升級到15.10時,您的sudoer或與其相關的特權或其組的更改的配置會發生變化。也許你在沒有root權限的情況下運行你的python並且它不能殺死提升的shell(導致sudo) –