[Python] 背景執行nohup, & 與 nohup.out

本篇提到的「背景」指的是: 在終端機模式下使用 [ctrl]-c, 並不會中斷的一個情境!

[Linux]背景執行py方法 雖然是在背景執行, 不會因為[ctrl]-c而中斷, 但會因為「終端機關閉後而中斷」。

中斷可能多個原因, 例如ssh連線到機器後, 操作時不小心將視窗關閉,或是網路斷線而關閉。

本次主要目的為: 「在離線或登出系統後,還能夠讓工作繼續進行」。

演示的code為my_nohup.py:

# coding:utf-8
from datetime import datetime
from time import sleep
import logging

Log_Format = "%(levelname)s %(asctime)s - %(message)s"

logging.basicConfig(filename = "mylog.log",
                    filemode = "w",
                    format = Log_Format,
                    level = logging.INFO)
logger = logging.getLogger()
logger.error("Our First Log Message")

while(1):
    sleep(5)

    print("print " + str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
    logger.info(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
    # print(1/0) # 輸出錯誤時使用

指令介紹

  • nohup: no hang up的縮寫, 不斷地運行。
  • &: 在後台運行,關掉終端會停止運行。
  • > : 標準輸出符號。
  • -u: 在nohup.out內可以看到print的訊息。

背景執行(nohup, &)

nohup python3 my_nohup.py &

758865 為背景執行的PID

執行完會出現一段,所有輸出都被重定向到一個名為nohup.out的文件中

nohup: ignoring input and appending output to 'nohup.out'

此時輸入ls指令會看到多出mylog.log和nohup.out

admins@labs:~$ ls
Dev  get-pip.py  mylog.log  my_nohup.py  nohup.out  Python-3.7.9

試著使用cat去看看這兩隻檔案, mylog.log會每5秒打印訊息, 但nohup.out是空的。

查看背景運行(若是關閉終端機後才使用指令,jobs已經無法看到後台跑得程序了, 需使用ps aux)

jobs -l

離開該終端機後, 背景仍會繼續執行這個服務, 可使用ps aux來查看。

[解決] nohup.out打開是空白問題

如果沒有指定導出的地方, 會在nohup.out檔案內, 但在執行時需使用
python -u
執行時使用下方指令:

nohup python3 -u my_nohup.py &

這樣print內的訊息都會在nohup.out了, 而log則是logger寫入的資料, 是分開的檔案。

指定輸出檔案(導出檔案)

可以指定導到其他檔案, 下方是導到my_print.txt

nohup python3 -u my_nohup.py > my_print.txt &

沒有nohup: ignoring input and appending output to ‘nohup.out’的訊息, 也沒有看到nohup.out的檔案。

這裡的>其實是 1> 的縮寫。

名稱代碼操作符號
標準輸入0< 或<<
標準輸出1>或>>或1> 或1>>
標準錯誤輸出22> 或2>>

通常後台運行重定向可以寫成:

mkdir logs
nohup python3 -u my_nohup.py > logs/command.log 2>&1 &

2>&1 是將「標準錯誤輸出(2)」重定向到「標準輸出(1)」, 簡單來說就是標準輸出和標準錯誤輸出都在同一份檔案, 導入logs文件夾下的command.log日誌文件。

標準輸出與標準錯誤輸出分開儲存

如果想要把錯誤輸出存到另一份檔案,把最後一行的註解拿掉, print(1/0)在最後運行時會出錯, 下方指令, 會把標準輸出到out.log, 標準錯誤輸出err.log

nohup python3 -u my_nohup.py > out.log 2>err.log &

下方為故意讓程式有出錯的狀況的圖片, 會看到out.log是原本的print日期時間, 而err.log則是遇到錯誤的訊息


補充:
鳥哥私房菜-離線管理問題

發佈留言

內容索引