Shell

如何在後台作業的 shell 腳本上執行反引號

  • July 30, 2022

此命令不會終止

echo `bash -c 'tail -f /dev/null & echo hello world'`

儘管事實上

bash -c 'tail -f /dev/null & echo hello world'

正確返回“hello world”

我正在嘗試將在反引號內評估的 bash 腳本中的命令作為背景。我實際上需要執行 eval 而不是 echo,對於這個範例,我使用的是 echo。有問題的腳本模擬了一個 ssh-agent,它通常輸出許多導出語句。但是,在腳本內部,我需要背景工作。

我嘗試使用disown,nohup$()代替反引號。似乎反引號總是等待所有子程序的終止。有沒有辦法繞過這個?我特別有興趣接收後台命令的 PID。

在:

echo `shell code`

這是不推薦使用的形式:

echo $(shell code)

shell code在子shell 及其整個輸出中進行評估,去除尾隨換行符,並且由於您忘記引用它,因此將 split+glob 作為參數傳遞給echo.

為此,shell 使該子 shell 的標準輸出成為管道,並且在管道的另一端,shell 讀取輸出直到文件結束,也就是說,直到所有具有其標準輸出的程序(或任何其他fd) 在該管道上打開,要麼關閉這些 fd,要麼終止。

在:

echo "$(sleep 10 & echo done)"

即使sleep 10是非同步執行並且子shell不等待它的終止,執行的程序sleep仍然在管道上打開它的stdout(fd 1)並且它會一直保持直到它退出,所以shell必須等到sleep終止知道沒有更多的輸出要讀取。

如果您將其更改為:

echo "$(sleep 10 > /dev/null & echo done)"

您會看到它sleep在後台執行時立即返回,因為sleep在這種情況下管道上沒有任何 fd 打開。

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