默默殺死subshel l?
我想實現類似Q/A 的東西,但要使用子外殼。這是我正在嘗試的一個最小範例:
(subshell=$BASHPID (kill $subshell & wait $subshell 2>/dev/null) & sleep 600) echo subshell done
我怎樣才能使它只
subshell done
返回而不是:./test.sh: line 4: 5439 Terminated ( subshell=$BASHPID; ( kill $subshell && wait $subshell 2> /dev/null ) & sleep 600 ) subshell done
編輯:我在這裡的術語可能是錯誤的,子shell是指第一組括號內的過程。
更新:
我想從實際程序中發布片段以獲取上下文,上面是一個簡化:
# If subshell below if killed or returns error connected variable won't be set (if [ -n "$2" ];then # code to setup wpa configurations here # If wifi key is wrong kill subshell subshell=$BASHPID (sudo stdbuf -o0 wpa_supplicant -Dwext -i$wifi -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 \ | grep -m 1 "pre-shared key may be incorrect" \ && kill -s PIPE "$subshell") & # More code which does the setup necessary for wifi ) && connected=true # later json will be returned based on if connected is set
筆記:
wait $subshell
不會工作,因為$subshell
它不是你正在執行的程序的子程序wait
。無論如何,你不會等待程序這樣做,wait
所以這並不重要。kill $subshell
將殺死子shell,但sleep
如果子shell 在執行時已成功啟動它,則不會kill
。但是,您可以sleep
在同一程序中執行exec
- 您可以使用 SIGPIPE 而不是 SIGTERM 來避免該消息
- 在列表上下文中不加引號的變數在
bash
.說了這麼多,你可以這樣做:
( subshell=$BASHPID kill -s PIPE "$subshell" & sleep 600 ) echo subshell done
(如果您想殺死而不僅僅是子shell,請替換
sleep 60
為,在這種情況下,您殺死它時甚至可能沒有時間執行)。exec sleep 60``kill``sleep``sleep
無論如何,我不確定你想用它來實現什麼。
sleep 600 &
sleep
如果這是您想要做的(或者(sleep 600 &)
如果您想sleep
從主 shell 隱藏該程序),這將是一種更可靠的在後台啟動的方式現在用你的實際
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
命令,請注意,它
sudo
確實會產生一個子程序來執行該命令(如果只是因為它可能需要記錄其狀態或之後執行一些 PAM 會話任務)。stdbuf
然而,將在同一個程序中執行,所以最後你將在的祖先wpa_supplicant
中擁有三個程序(除了腳本的其餘部分) :wpa_supplicant
- 子殼
- sudo 作為 1 歲的孩子
- wpa_supplicant(之前執行 stdbuf)作為 2 的孩子
如果您殺死 1,則不會自動殺死 2。但是,如果您殺死 2,除非它帶有無法攔截的 SIGKILL 之類的信號,否則它將殺死 3,因為
sudo
它會將收到的信號轉發給它執行的命令.無論如何,這不是您要在這裡殺死的子shell,它是 3 或至少 2。
現在,如果它正在執行
root
而腳本的其餘部分沒有執行,您將無法如此輕鬆地殺死它。你需要
kill
做 asroot
,所以你需要:sudo WIFI="$wifi" bash -c ' (echo "$BASHPID" && exec stdbuf -o0 wpa_supplicant -Dwext -i"$WIFI" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 ) | { read pid && grep -m1 "pre-shared key may be incorrect" && kill -s PIPE "$pid" }'
這樣,
wpa_supplicant
將在與$BASHPID
子shell 相同的程序中執行,就像我們使用exec
.我們通過管道獲取 pid 並
kill
以 root 身份執行。請注意,如果您準備再等一會兒,
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 | grep -m1 "pre-shared key may be incorrect"
下次它在消失後向該管道寫入內容時會
wpa_supplicant
使用 SIGPIPE 自動終止(由系統執行,因此沒有權限問題) 。grep
一些 shell 實現不會等待
sudo
aftergrep
返回(讓它在後台執行直到它獲得 SIGPIPEd),並且使用bash
,您也可以使用grep ... <(sudo ...)
語法來執行此操作,其中bash
不等待sudo
任何一個 aftergrep
返回。找到匹配項後,Grep 的更多資訊退出緩慢?