Bash

Bash 使用 && 而不是 with ; 創建子程序對於 nohup 程序

  • July 22, 2021
  • 我有一個 macbook(預設 shell 是 zsh)
  • 我有一個可執行的 python 腳本(srcript1.py)。
  • 我使用另一個可執行腳本(稱為starter)在我的電腦啟動時執行script1.py ,執行****starter 的終端視窗會自動打開和關閉,並且script1.py程序仍然作為單獨的程序執行。(當我的電腦打開時, starter會通過一個 szh shell 的實例自動執行)。原始的啟動腳本文件如下:
#!/bin/bash

cd /script1; nohup ./script1.py &

這個腳本工作正常,一切都很好。

但是,我試圖了解當我在腳本中使用 (&&) 而不是 (;) 時會發生什麼。IE

#!/bin/bash

cd /scritp1 && nohup ./script1.py &

我的問題是這也有效,但每當我嘗試終止我的 python 腳本程序時,我注意到 szh 或其他東西(可能是 bash 程序)的終端實例正在作為程序執行。即如果我在終端呼叫ps我得到

ps -ef | grep "script1" 
123 14679     1   0  2:12PM ??       0:00.00 /bin/bash /script1 starter
123 14680 14679   0  2:12PM ??       0:03.46 /PythonFolder/python ./script1.py
123 14690 14683   0  2:12PM ttys000  0:00.00 grep scrip1

對於使用**&&的腳本啟動器**

ps -ef | grep "script1" 
123 14644     1   0  2:08PM ??       0:03.46 /PythonFolder/python ./script1.py
123 14652 14647   0  2:08PM ttys000  0:00.00 grep scrip1

對於使用的啟動腳本**;**

為什麼我在一個版本中有兩個程序,而在另一個版本中只有一個?我試圖理解為什麼執行**starter的 szh 在我使用****&&時會創建一個執行我的 python 腳本的子程序,以及為什麼它會在我的 starter 腳本使用時終止;**並使 python 腳本作為單個程序執行。

當我使用使用**&&的腳本執行****starter時,終端應用程序會出現並關閉,但會留下兩個正在執行的程序(在本例中為1467914680**)。

如果我使用啟動腳本使用**;** 我想殺死我只想呼叫的 python.py 程序

kill 14644

但是,如果我使用使用**&&的****啟動**腳本並且我想殺死兩個程序,我注意到殺死子程序或殺死父程序然後子程序起作用,即

kill 14680

或者

kill 14679; kill 14680

我還注意到我可以殺死父程序

kill 14679

我的 python 腳本會像往常一樣繼續執行。

關鍵在於命令列表的工作方式(在此處引用 Bash 手冊,因為您使用#!/bin/bash的是 shebang 行):

列表是一個或多個管道的序列,由運算符“;”、“&”、“&&”或“||”之一分隔,並可選地以“;”、“&”或新隊。

在這些列表運算符中,&& 和 || 具有相同的優先級,其次是 ; 和 &,它們具有相同的優先級。

管道是由一個或多個命令組成的序列,由|or分隔|&)。

這意味著在

cd /script1; nohup ./script1.py &

由於運算符之間的優先規則,shell 會看到 list cd /script1,由 終止;,然後在“主”shell 中同步執行,而 list nohup ./script1.py,由 終止&,然後在生成的單獨程序中非同步執行。

另一方面,在

cd /scritp1 && nohup ./script1.py &

shell 看到 AND 列表cd /scritp1 && nohup ./script1.py,由 終止&,並非同步執行整個列表。這需要生成一個新bash程序來執行列表本身(在後台),這反過來又為您的 Python 腳本生成一個單獨的程序。

關於kill:殺死父程序不會自動殺死其子程序。這是標準的外殼行為。在您的&&列表中,殺死子程序允許其父程序終止,因為父程序所做的只是等待子程序返回。

如果您想nohup ./script1.py根據 AND 列表的成功有條件地執行cd /script1 避免為 AND 列表生成 shell,您可以將第二個元素括在花括號中:

cd /scritp1 && { nohup ./script1.py & }

或使用條件塊:

if
 cd /scritp1
then
 nohup ./script1.py &
fi

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