Bash

將 Subshel l 後台程序 pid 分配給變數

  • September 24, 2014

我目前正在子外殼中啟動後台程序,並且想知道如何將其 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] 21578go to /dev/nullbutsleep的 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"

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