進程完成後執行 bash 指令

進程完成後執行 bash 指令

我有兩個使用 GPU 和訓練 ML 模型的腳本。我想在睡覺前啟動它們,這樣它們就會在晚上起作用,我希望在早上看到一些結果。

但由於 GPU 記憶體有限,我想串行運行它們而不是並行運行。

我可以用python train_v1.py && python train_v2.py;但假設我開始訓練train_v1.同時,由於訓練時間較長,我開始並完成了第二個腳本的實現,train_v2.py我想在python train_v1.py完成後自動運行它。

我怎樣才能做到這一點?謝謝。

答案1

這是一種不涉及循環和檢查其他進程是否仍然存在的方法,或者train_v1.py以與通常所做的方式不同的方式呼叫:

$ python train_v1.py
^Z
[1]+  Stopped                 python train_v1.py
$ % && python train_v2.py

^Z是我在進程運行時按Ctrl+通過向其發送信號進入睡眠狀態。然後,我告訴 shell 用 喚醒它,將其用作命令,我可以在末尾添加 。這使得它的行為就像您從一開始就做的一樣。Ztrain_v1.pySIGTSTP%&& python train_v2.pypython train_v1.py && python train_v2.py

相反%,您也可以使用fg.這是同一件事。如果您想了解有關 shell 的這些類型功能的更多信息,可以閱讀bash 線上說明頁的「作業控制」部分

編輯:如何繼續加入到佇列中

正如 jamesdlin 在評論中指出的那樣,如果您嘗試train_v3.py在 v2 開始之前繼續添加模式,您會發現不能:

$ % && python train_v2.py
^Z
[1]+  Stopped                 python train_v1.py

只會train_v1.py因為尚未開始而停止train_v2.py,並且您無法停止/暫停/睡眠甚至尚未開始的東西。

$ % && python train_v3.py

會導致相同的結果

python train_v1.py && python train_v3.py

因為%對應最後一個掛起的進程。v3人們不應該嘗試這樣添加,而應該使用歷史記錄:

$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py

人們可以像上面那樣進行歷史擴展,或者使用鍵綁定(如 up)調用最後一個命令並將 v3 添加到末尾。

$ % && python train_v2.py && python train_v3.py

這是可以重複的事情,以向管道中添加更多內容。

$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py
^Z
[1]+  Stopped                 python train_v1.py
$ !! && python train_v4.py
% && python train_v2.py && python train_v3.py && python train_v4.py

答案2

如果你已經啟動了python train_v1.py,你可以使用pgrep輪詢該進程直到它消失,然後執行你的第二個Python腳本:

while pgrep -u "$USER" -fx 'python train_v1.py' >/dev/null
do
    # sleep for a minute
    sleep 60
done
python train_v2.py

透過使用-f和 ,-x您可以匹配用於啟動第一個 Python 腳本的確切命令行。在某些系統上,pgrep實作一個-q選項,使其安靜(就像grep -q),這意味著/dev/null不需要重定向到。

-u選項將匹配限制為您正在運行的命令(而不是同一系統上的朋友或其他人)。

如果您還沒有開始第一個腳本:

正如評論中提到的,您可以在第一個腳本之後立即啟動第二個腳本。事實上,第二個腳本不存在,或尚未準備好運行,並不重要(只要它在第一個腳本完成時準備好運行):

python train_v1.py; python train_v2.py

這樣做將啟動第二個腳本,無論第一個腳本的退出狀態如何。正如您在問題中所示,使用&&代替;也可以工作,但需要第一個腳本成功完成才能啟動第二個腳本。

答案3

您可以使用以下命令啟動第一個腳本

python train_v1.py; touch finished

然後簡單地創建一個循環來定期檢查是否finished存在:

while [ ! -f finished ] ; do     
    sleep 5
done
python train_v2.py
rm finished

答案4

如果您不需要知道第一個腳本的退出狀態,那麼我推薦類似的東西拘薩羅南達寫了什麼

如果您確實需要知道退出狀態(在這種情況下您可能不需要,但其他人可能會尋找執行此操作的解決方案),那就更複雜了。我寫了一個Linux 小型實用程式pwait它允許您等待進程完成並找出其退出狀態。

相關內容