如何在同一個 shell 腳本中將一個程序的 PID 傳遞給另一個程序?
好的,所以這可能是一個非常愚蠢的問題,而且我不經常編寫 shell 腳本。我正在嘗試在後台啟動 3 個程序,在 shell 腳本中一個接一個地啟動,例如:
#!/bin/sh PROCESS1 & PROCESS2 & PROCESS3 &
這是問題所在。我需要以與所示相同的順序啟動這些程序。此外,PROCESS2 的 PID 需要作為命令行參數傳遞給 PROCESS3。所有這些程序都在無限循環中執行,並且在 3 個單獨的終端中執行時它們確實可以順利執行。
我試過:
#!/bin/sh PROCESS1 & PROCESS2 & PID_PROCESS2=$! PROCESS3 ${PID_PROCESS2} &
這會啟動 PROCESS1 和 PROCESS3,但 PROCESS2 會立即退出而不會列印任何錯誤。它只是消失了。ps 命令它沒有顯示 PROCESS2 的痕跡。列印 PID_PROCESS2 會給出一些值“p”,並且 PROCESS3 以值“p”作為參數執行得很好。有什麼問題,我缺乏什麼?
可能很重要的細節
1)在上面的範例中,我使用限定路徑來呼叫各個程序,它們都是本機二進製文件並且位於同一目錄中。例如,
#!/bin/sh /usr/bin/PROCESS1 &
ps的輸出如前所述,
$ps | grep "/path/to/PROCESS" 10064 root 16536 S /path/to/PROCESS1 10066 root 11084 S /path/to/PROCESS3 10065
這清楚地表明 PROCESS2 已啟動但由於某種未知原因退出。
2)PROCESS2 通過 FIFO(命名管道)與 PROCESS1 通信,這是一種單向通信。
解決方法
#/bin/sh /path/to/PROCESS1 & /path/to/PROCESS2 & PROCESS2_PID=$! export P2PID=${PROCESS2_PID} sh -c "/path/to/PROCESS3 ${P2PID}"
這似乎通過一個額外的 sh 程序來完成這項工作。
$ps | grep "/path/to/PROCESS" 10174 root 16536 R /path/to/PROCESS1 10175 root 71720 S /path/to/PROCESS2 10177 root 27772 S sh -c /path/to/PROCESS3 10175 10076 root 11084 S /path/to/PROCESS3 100175
但我仍然不知道為什麼會這樣。有人可以建議在這種情況下發生了什麼樣的“魔法”嗎?
根據您的描述,這聽起來 PROCESS2 存在根本問題,導致它退出。如果我用 3 個程序對您所描述的內容進行建模,那麼當您將 3 個程序作為後台處理然後擷取並將第二個程序的 PID 傳遞給程序 3 時,它通常會像預期的那樣工作。
例子
範例腳本
$ cat runny.bash #!/bin/bash proc3func() { echo $1 sleep 7 & } sleep 9 & sleep 8 & PID2=$! proc3func ${PID2} &
範例執行
$ ./runny.bash ; sleep 2; ps -eaf 4279 UID PID PPID C STIME TTY TIME CMD ... vagrant 4278 1 0 20:21 pts/1 00:00:00 sleep 9 vagrant 4279 1 0 20:21 pts/1 00:00:00 sleep 8 vagrant 4282 1 0 20:21 pts/1 00:00:00 sleep 7
在上面的輸出中,我們可以看到 PID,4279 被回顯到螢幕上,隨後的輸出
ps -eaf
顯示了我們的 3 個程序。調試
我建議啟用
set -x
,以便您可以在執行腳本或像這樣執行它時遵循正在執行的命令:$ bash -x ./runny.bash + PID2=4612 + sleep 9 + sleep 8 + proc3func 4612 + echo 4612 4612 + sleep 7