Bash

在 Bash 中設置子程序的信號遮罩

  • July 14, 2018

這是我的問題 - 我正在嘗試編寫一個小的包裝腳本,在呼叫 Xorg 時添加一個命令行參數(我無權訪問呼叫者的原始碼。)看起來很簡單,但我現在正在執行的問題into 是呼叫者正在等待USR1來自 Xorg 的信號。從 XSERVER 手冊頁:

SIGUSR1

該信號的使用與上述任何一種都完全不同。當伺服器啟動時,它會檢查它是否繼承了 SIGUSR1 作為 SIG_IGN 而不是通常的 SIG_DFL。在這種情況下,伺服器在設置各種連接方案後向其父程序發送一個 SIGUSR1。Xdm 使用此功能來辨識何時可以連接到伺服器。

我以為我可以簡單地擷取信號並轉發它:

#!/bin/bash
parent_trap(){
  echo sending USR1 to $PPID &> /tmp/wrapper.log
  kill -USR1 $PPID
}
trap "parent_trap" USR1
Xorg $@ (extra stuff) &
wait

但當然這不起作用,因為腳本本身是由呼叫者忽略USR1. 我認為我需要做的是讓腳本停止忽略信號,但也以某種方式啟動 Xorg 並USR1忽略(從手冊頁觸發行為。)

這在 Bash/其他腳本語言中是否可行?出於幾個原因,我希望避免編譯解決方案,但這並非不可想像。也有可能我完全在考慮這個錯誤,並且還有其他方法可以USR1從 Xorg 到呼叫者。

你的新腳本

與其嘗試對信號做一些花哨的事情,不如直接這樣做:

$ cat xorg_wrapper
#!/bin/bash

exec Xorg $@ (extra stuff)

這個怎麼運作

為了說明上面的內容,這裡有一個更詳細的範例,有助於展示exec上述腳本中的機制。

$ cat xorg.bash
#!/bin/bash

echo "script's PID: $$"
sleep 5
echo "starting fakeXorg..."
exec sleep 5

# Nothing below here will execute due to exec
echo $!
echo "fakeXorg finished..."
sleep 5

這將按照您的指定啟動 Xorg,但是因為我們使用該exec命令Xorg將假定相同的 PID 並將我們的xorg.bash腳本替換為它自己。

**注意:**上面最後 3 行的目的是證明在命令xorg.bash執行後不再執行/執行。exec sleep ...

例子

首先我們執行我們的腳本:

$ ./xorg.bash
script's PID: 22471

...5 seconds passes...

starting fakeXorg...

...now the exec runs and 5 more seconds pass...

$

如果我們要在另一個 shell 中使用它來監控它,ps auxf我們會看到這個。

第 1 階段 - xorg.bash 預執行

$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.1 113176  1400 pts/2    S+   20:43   0:00                      \_ /bin/bash ./xorg.bash
root     22472  0.0  0.0 107948   348 pts/2    S+   20:43   0:00                          \_ sleep 5

第 2 階段 - xorg.bash 後執行

$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.0 107948   352 pts/2    S+   20:43   0:00                      \_ sleep 5

請注意,階段 1xorg.bash的 PID 為 22471,但在階段 2,exec sleep 5現在具有相同的 PID,即 22471。

後面的行exec ...

exec命令的功能導致目前 shell 被另一個執行檔替換:

   $ help exec
    ...
        Replace the shell with the given command.

因此,xorg.bash永遠不會執行中的任何命令,因為在該點處exec ....xorg.bash不再作為程序存在,已被sleep命令替換。

參考

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