在Linux執行任務時,如果鍵入Ctrl+C退出進行其他任務或者關閉當前session
當前任務就會終止 要想不讓進程停止或者讓進程在后台運行,就需要一些命令,nohup和&就是一種非常好的方式
首先以執行一個python腳本為例:
python test.py
nohup
和&
的區別
&:后台運行,但當用戶退出(掛起)的時候,命令自動也跟着退出
什么意思呢? 意思是說, 當你在執行 python test.py &
的時候, 即使你用ctrl C
, 那么python test.py
照樣運行(因為對SIGINT信號免疫)。 但是要注意, 如果你直接關掉shell后, 那么, 這個python進程同樣消失。 可見, &的后台並不硬(因為對SIGHUP信號不免疫)。
nohup: 即no hang up,不掛斷的運行
nohup的意思是忽略SIGHUP信號, 所以當運行nohup python test.py
的時候, 關閉shell, 那么這個python進程還是存在的(對SIGHUP信號免疫)。 但是, 要注意, 如果你直接在shell中用Ctrl C, 那么, 這個python進程也是會消失的(因為對SIGINT信號不免疫)
注意並沒有后台運行的功能,就是指,用nohup運行命令可以使命令永久的執行下去,和用戶終端沒有關系,例如我們斷開SSH連接都不會影響他的運行,注意了nohup沒有后台運行的意思;&才是后台運行
綜合使用
如果想讓進程在后台不掛斷的運行,需要nohup
和&
結合起來使用
nohup nohup python test.py &> /var/log/python.log &
nohup語法:
nohup Command [ Arg ... ] [ & ]
nohup 命令運行由 Command參數和任何相關的 Arg參數指定的命令,忽略所有掛斷(SIGHUP)信號。在注銷后使用 nohup 命令運行后台中的程序。要運行后台中的 nohup 命令,添加 & ( 表示“and”的符號)到命令的尾部。
如果不將 nohup 命令的輸出重定向,輸出將附加到當前目錄的nohup.out
文件中。如果當前目錄的 nohup.out 文件不可寫,輸出重定向到 $HOME/nohup.out 文件中。如果沒有文件能創建或打開以用於追加,那么 Command 參數指定的命令不可調用。如果標准錯誤是一個終端,那么把指定的命令寫給標准錯誤的所有輸出作為標准輸出重定向到相同的文件描述符。
實戰講解
首先准備一個python測試代碼,是一個輸出HelloWorld和數字的死循環腳本,每輸出一行就等待1秒:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import time
var = 1
while var > 0 : # 該條件永遠為true,循環將無限執行下去
print "HelloWorld: ", var
var = var +1
time.sleep(1) #每輸出一行就休眠1秒
1. 前台運行
執行下列命令前台運行python腳本是什么情況呢?
python test.py
程序每隔一秒會在終端輸出一個字符串。
此時如果鍵入Ctrl+C ,程序會收到一個SIGINT信號,如果不做特殊處理,程序的默認行為是終止(如上圖)。
2. 后台運行
執行下面的命令在后台運行這個python腳本:
python test.py &
如上圖,首先會在終端顯示進程號是8778
如果鍵入Ctrl + C,發出SIGINT信號,程序會繼續運行嗎?
下圖所示,鍵入Ctrl + C程序仍然會繼續運行:
執行ps -ef|grep test.py
查詢一下,程序進程確實存在,如下圖所示:
此時如果關閉session即關閉xshell,程序會收到一個SIGHUP信號,此時會怎么樣呢?
重新打開xshell的session,:
如上圖,程序不會繼續輸出,而且執行ps -ef|grep test.py
剛剛打開的進程以及被關閉了。
3. 使用nohup運行腳本
如果使用nohup命令來運行python腳本的話,會是怎樣的情況呢?
執行以下命令:
nohup python test.py
如上圖,使用nohup 運行程序test.py,會發現:
- 前台沒有出現進程號
- 有一個“忽略輸入,輸出至nohup.out”的提示
- hello的輸出也沒有出現在前台
如上圖,在另一個xshell的session的窗口執行ps -ef|grep test.py
,會發現腳本已經在運行了,進程號是20085
在前一個圖中提示輸出至nohup.out的提示,那么我們在新打開的窗口去看看這里面是啥。
vi nohup.out
如上圖,腳本的日志會在這個文件輸出。
此時,如果我們關閉原來執行腳本的xshell的session,程序會收到一個SIGHUP信號,程序會不會關閉呢?
如上圖,我們在新打開的xshell創建執行ps -ef | grep test.py
發現,這個PID為20085的python進程還存在
此時只能通過kill命令來殺死進程了:
kill -9 20085
然后,再次ps一下,如下圖,進程已經被殺掉了
此時重新使用nohup執行一下這個python腳本:nohup python test.py
然后鍵入Ctrl+C,並且執行ps -ef | grep test.py
查看一下進程:
如上圖所示,鍵入Ctrl+C后,程序收到SIGINT信號后,進程直接關閉了
4. 后台不掛斷運行
nohup
和&
一起使用,我們來看看是什么情況:
使用以下指令運行程序:
nohup python test.py &
如上圖,使用nohup python test.py &
運行程序后,可以看到:
- 會在終端顯示進程號是21503
- 也會有一個“忽略輸入,輸出至nohup.out”的提示
- 鍵入Ctrl + C,發送SIGINT信號,似乎沒反應。
關閉session,發送SIGHUP信號,再打開一個session窗口ps一下:
如上圖,ID為21503的進程依然存在,后續也只能用kill來關閉它。
結論
使用&后台運行程序:
- 結果會輸出到終端
- 使用Ctrl + C發送SIGINT信號,程序免疫
- 關閉session發送SIGHUP信號,程序關閉
使用nohup運行程序:
- 結果默認會輸出到nohup.out
- 使用Ctrl + C發送SIGINT信號,程序關閉
- 關閉session發送SIGHUP信號,程序免疫
使用nohup和&配合來啟動程序:
- 同時免疫SIGINT和SIGHUP信號
最佳實踐方案:
不要將信息輸出到終端標准輸出,標准錯誤輸出,而要用日志組件將信息記錄到日志里
nohup命令可以將日志輸入到文件中
- 如果不指定輸出文件,默認輸出到當前目錄下的
nohup.out
文件 - 如果當前目錄的 nohup.out 文件不可寫,輸出重定向到 $HOME/nohup.out 文件中。
舉個例子:
nohup python test.py > test.log 2>&1 &
nohup ping www.baidu.com > ping.log 2>&1 &
Linux輸出重定向: