介紹在 Ubuntu 環境下使用 nohup
命令將 Python 程式放到背景執行的用法。這在需要長時間運行,且不希望因為終端機關閉而中斷程式的情況下非常實用。
nohup
命令的基本概念
nohup
是 "no hang up" 的縮寫,它的主要作用是讓程式在使用者登出終端機後,仍然能夠繼續執行。當你使用 nohup
啟動一個程式時,它會忽略 SIGHUP (hangup) 訊號。這個訊號通常在終端機連線中斷時發送給所有與該終端機相關的程序。
使用 nohup
執行 Python 程式於背景
以下是基本的用法和步驟:
-
確保你的 Python 程式可以正常執行: 首先,請確認你的 Python 程式 (
your_script.py
) 在前台可以正確地執行。你可以使用以下命令測試:Bashpython your_script.py
-
使用
nohup
執行 Python 程式並放到背景: 要使用nohup
將你的 Python 程式放到背景執行,你可以使用以下命令:Bashnohup python your_script.py &
nohup
: 這個命令會讓後面的程式忽略 SIGHUP 訊號。python your_script.py
: 這是你要執行的 Python 命令。&
: 這個符號放在命令的最後面,表示將該命令放到背景執行。執行後,終端機會立即返回提示符號,你可以繼續輸入其他命令。
-
查看輸出:
nohup
會將程式的標準輸出 (stdout) 和標準錯誤輸出 (stderr) 預設重新導向到目前目錄下一個名為nohup.out
的檔案中。你可以使用cat
、less
或tail
等命令來查看這個檔案的內容,以了解程式的執行情況。Bashcat nohup.out less nohup.out tail -f nohup.out # 實時追蹤輸出
-
指定輸出檔案: 如果你想要將輸出導向到特定的檔案,可以使用重新導向符號
>
或>>
。- 覆蓋寫入:
Bash
nohup python your_script.py > my_output.log &
- 追加寫入:
Bash
nohup python your_script.py >> my_output.log &
- 同時導向標準輸出和標準錯誤輸出到同一個檔案:
或者更簡潔的寫法:Bashnohup python your_script.py > output.log 2>&1 &
Bashnohup python your_script.py &> output.log &
- 覆蓋寫入:
-
查看背景執行的程序: 你可以使用
jobs
或ps
命令來查看目前在背景執行的程序。-
jobs
: 這個命令會列出目前終端機會話中放到背景執行的任務。但如果你關閉了終端機,jobs
就無法顯示這些程序了。 -
ps
: 這個命令可以列出目前系統中正在執行的程序。你可以搭配grep
來過濾出你的 Python 程序。Bashps aux | grep "python your_script.py"
這個命令會顯示包含 "python your_script.py" 的所有程序資訊。
-
-
終止背景執行的程序: 要終止一個在背景執行的程序,你需要先找到它的程序 ID (PID)。你可以使用
ps aux | grep "python your_script.py"
命令找到 PID,通常是輸出的第二欄的數字。然後使用kill
命令加上 PID 來終止程序。Bashkill <PID>
如果程序沒有正常終止,你可以嘗試使用
kill -9
強制終止它。Bashkill -9 <PID>
總結用法範例:
假設你的 Python 程式是 my_long_task.py
,你想要在背景執行它,並將輸出寫入到 task.log
檔案中,你可以使用以下命令:
nohup python my_long_task.py > task.log 2>&1 &
執行後,你可以關閉你的終端機,這個 Python 程式仍然會在伺服器上繼續執行,並且所有的輸出都會被記錄在 task.log
檔案中。
[use /dev/null ]
如果你不希望 nohup
產生預設的 nohup.out
檔案,或者你指定了其他的輸出檔案,但現在想避免這些檔案的寫入以減少對硬碟讀寫壽命的影響,你可以將標準輸出 (stdout) 和標準錯誤輸出 (stderr) 重新導向到一個特殊的「空設備」檔案,即 /dev/null
。
/dev/null
是一個特殊的檔案,所有寫入到這個檔案的資料都會被丟棄,而從這個檔案讀取資料則會立即得到檔案結束 (EOF)。將輸出導向到 /dev/null
實際上就是將輸出「丟掉」,不會有任何資料被寫入到硬碟。
以下是如何修改你的 nohup
命令來避免寫入 log 檔案:
1. 丟棄標準輸出 (stdout):
如果你只想丟棄程式的標準輸出,可以使用 >
將其導向到 /dev/null
:
nohup python your_script.py > /dev/null &
2. 丟棄標準錯誤輸出 (stderr):
如果你只想丟棄程式的標準錯誤輸出,可以使用 2>
將其導向到 /dev/null
:
nohup python your_script.py 2> /dev/null &
3. 同時丟棄標準輸出和標準錯誤輸出:
如果你想同時丟棄標準輸出和標準錯誤輸出,可以將它們都導向到 /dev/null
。有幾種寫法:
-
分別導向:
Bashnohup python your_script.py > /dev/null 2> /dev/null &
-
先導向 stdout 到 /dev/null,然後將 stderr 導向到與 stdout 相同的位置(即 /dev/null):
Bashnohup python your_script.py > /dev/null 2>&1 &
-
使用
&>
(bash 4 及更新版本):Bashnohup python your_script.py &> /dev/null &
這個語法會將標準輸出和標準錯誤輸出都導向到
/dev/null
。
選擇哪種方式取決於你的需求:
- 如果你完全不關心程式的任何輸出(包括正常的資訊和錯誤訊息),那麼同時導向標準輸出和標準錯誤輸出到
/dev/null
是最直接的方法。 - 如果你希望偶爾能夠檢查程式是否出錯(即使沒有詳細的 log),你可能需要考慮其他記錄錯誤的方式,或者在開發和測試階段開啟 log 記錄,在正式長時間運行時再禁用。
注意事項:
- 將輸出導向到
/dev/null
後,你將無法看到程式運行的任何資訊或錯誤訊息。這可能會在程式出現問題時增加除錯的難度。 - 如果你的 Python 程式本身有其他的檔案寫入操作,這些操作仍然會發生,並且不受你使用
/dev/null
重新導向nohup
輸出的影響。
總之,使用 /dev/null
是一個有效避免 nohup
產生 log 檔案的方法,但你需要權衡這樣做可能帶來的除錯不便。在決定是否使用這種方法時,請仔細考慮你的應用場景和對程式輸出的需求。
沒有留言:
張貼留言