Bash
將 Subshel l 後台程序 pid 分配給變數
我目前正在子外殼中啟動後台程序,並且想知道如何將其 pid 號分配給子外殼範圍之外的變數?
我嘗試了許多不同的方法,但
MYPID
始終保持設置為0
.MYPID = 0; ({ sleep 2 & }; $MYPID=$!) ({ sleep 2 & }; echo $!) > $MYPID
它返回值的唯一方法是:
$MYPID=$({ sleep 2 & }; echo $!)
但是,這會丟棄後台程序指令,並且只會在 2 秒後返回結果。
bash
非互動式時不應列印作業狀態。如果這確實是一個互動式的
bash
,你可以這樣做:{ pid=$(sleep 20 >&3 3>&- & echo "$!"); } 3>&1
我們希望
sleep
’s stdout 回到原來的位置,而不是輸入$pid
變數的管道。因此,我們將外部標準輸出保存在文件描述符 3 ( ) 中,並在命令替換中3>&1
恢復它。sleep
所以pid=$(...)
一旦echo
終止就返回,因為沒有任何東西可以打開文件描述符到 feed 的管道$pid
。但是請注意,因為它是從子 shell 啟動的(這裡是命令替換),所以它
sleep
不會在單獨的程序組中執行。因此,sleep 20 &
例如,就終端的 I/O 而言,它與執行不同。也許更好的辦法是使用一個支持產生不受歡迎的後台作業的 shell,比如
zsh
你可以做的:sleep 20 &! pid=$!
使用
bash
,您可以將其近似為:{ sleep 20 2>&3 3>&- & } 3>&2 2> /dev/null; pid=$!; disown "$pid"
bash
輸出[1] 21578
到標準錯誤。同樣,我們在重定向到 /dev/null 之前保存 stderr,並為sleep
命令恢復它。這樣,[1] 21578
go to/dev/null
butsleep
的 stderr 照常進行。如果您要將所有內容重定向到 /dev/null ,您可以簡單地執行以下操作:
{ apt-get update & } > /dev/null 2>&1; pid=$!; disown "$pid"
僅重定向標準輸出:
{ apt-get-update 2>&3 3>&- & } 3>&2 > /dev/null 2>&1; pid=$!; disown "$pid"