Linux

如何為執行腳本的 Bash 程序設置 CHILD_SUBREAPER 標誌?

  • May 27, 2020

我想PR_SET_CHILD_SUBREAPER為執行我的腳本的 Bash 程序設置程序標誌,這樣我就可以在其生命週期內獲得創建(並且可以以非有序方式被殺死)的子程序樹。基本上,我希望 Bash 自己呼叫prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);,但我還沒有找到實現這一目標的方法。有什麼建議嗎?

即使存在涉及使用 Bash 內置函式libc.so.6 prctl()直接呼叫(a-la Python )的狡猾解決方案(如果存在),我也可以。ctypes

既然你提到它對你很好,我覺得有必要介紹一下 bash 的等價物……

ctypes.sh , bash 的外來函式介面

這是一個 bash 的共享對象外掛,載入了 bash 的enable -f機制:

enable [-a] [-dnps] [-f filename] [name ...]

-f選項意味著在支持動態載入的系統上從共享對象文件名載入新的內置命令名稱。

並用C語言實現。它至少適用於大多數 Linux 發行版和 FreeBSD。

您必須先編譯並安裝它。主要特點是能夠從 shell 使用幾乎任何庫呼叫或系統呼叫。struct儘管當內置函式無法自動重建它們時,需要結構的呼叫可能會變得更加複雜。

在目前 bash shell、amd64 (x86_64) 架構和 Linux 核心 5.6 上鍵入的範例(在某些情況下,常量取決於架構和(更不常見的)核心版本):

$ source /usr/local/bin/ctypes.sh
$ dlcall -r int prctl int:36 ulong:1 ulong:0 ulong:0 ulong:0
int:0
$ echo $DLRETVAL # you can't use $() above to get the result since that would be a subshell
int:0
$ echo $$; bash -c 'echo $$; sleep 99 & echo $!; disown -a'
14767
16761
16762
$ pstree -p $$
bash(14767)─┬─pstree(16778)
           └─sleep(16762)

sleep失去其父程序( pid 16761)的程序bash已被目前shell而不是init程序繼承:它工作。

請注意,PR_SET_CHILD_SUBREAPER必須替換為/usr/include/linux/prctl.h在此系統中找到的值(和類型):

#define PR_SET_CHILD_SUBREAPER    36

您必須檢查文件才能正確使用它。

此外,shell 的標準wait可能無法按預期工作:shell 沒有生成該sleep命令,因此該wait命令不會執行任何操作。您可能需要投資 dlcalling wait(), waitpid()& co。這可能很困難,因為 bash 本身會wait()在每次執行命令時更改設置並使用 -like 呼叫,因此可能會出現一些無法預料的互動來處理這些繼承的程序。


使用gdb

這將獲得與以前相同的結果(必須有一些選項來使其不那麼冗長):

$ gdb -ex 'call (int)prctl((int)36,(long)1,(long)0,(long)0,(long)0)' -ex detach -ex quit -p $$

引用自:https://unix.stackexchange.com/questions/589309