Shell-Script

Bash:用後台作業替換命令

  • October 14, 2021

我試圖在 bash 的函式中觸發並忘記一個程序。我希望此函式返回與程序確實已被觸發的事實相對應的狀態,並檢索函式的輸出以獲取子程序的 PID。所以我寫道:

my_ping() {
   # ... param check which potentially return 1

   ping "$1" &
   local pid
   pid="$!"
   echo "$pid"
   return 0
}

當用命令替換呼叫它時,函式阻塞並且永不返回(它不會阻塞在命令替換之外)

main() {
 
 # my_ping www.google.com # does not block and print PID

 # Blocks waiting for ping to terminate
 local mp_pid
 mp_pid=$(my_ping www.google.com)
}

main "$@"

我不明白為什麼在這種情況下功能塊,我嘗試了各種方法(setsid、disown 等)但都沒有成功,但我只是不太了解正在發生的事情。任何指針來理解這種情況?

您應該重定向ping其他地方的輸出而不是其預設值(由命令替換創建的管道)。只要任何程序仍然持有對該管道寫入端的引用,主 shell 將不會獲得 EOF,並且仍將等待以獲取命令替換的所有輸出。

例如,將其重定向到腳本的原始標準輸出:

my_ping() {
   ...
   ping "$1" >&"$out" &
   ...
}
main() {
   exec {out}>&1
   ...
   mp_pid=$(my_ping www.google.com)
}

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