Linux基礎問題處理/Linux之使用nohup,&及screen運行後臺任務的示例和區別

說明

本文轉載於https://beltxman.com/2524.html

使用SSH終端(比如putty,xshell)連接Linux服務器上運行比較耗時任務,可能需要幾個小時甚至幾天才能完成,這時候終端被佔據,我們還要做其他的任務呢,所以需要將這一類耗時任務放到後臺來跑,只需要記錄好日誌就行了,有下面這些常用方法來實現這個需求。

command &

在終端輸入command &運行,這時候使用Ctrl + C中止命令將會失效,因爲對&後臺運行SIGINT信號免疫,程序會繼續運行。但如果你直接關掉終端,進程將跟着中止。可見,使用&後臺運行的進程會被SIGHUP信號中止,但是你如果用exit命令正常退出終端,程序將繼續運行在後臺不會中止。

說明⚠️:

(1)SIGINT信號:程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl-C)時發出,用於通知前臺進程組終止進程

(2)SIGHUP信號:終端連接結束時發出, 通常是關閉終端, 通知同一session內的各個進程組

nohup command

標準輸出會被默認追加到當前目錄下的nohup.out中,如果當前目錄的nohup.out文件不可寫,輸出重定向到$HOME/nohup.out文件中。

那麼,我們很容易想到將這兩個特性綜合一下這樣運行命令:

nohup command > /home/user/myfile.log 2>&1 &

這樣將會在後臺一直執行這個任務直到完成,並將程序標準輸出(1)標準錯誤(2)都定向到/home/user/myfile.log文件中。

screen 工具

screen 可以理解爲一個會話窗口管理工具,對於一般的使用,我們只需要會使用下面操作即可:

# 使用yum安裝screen
yum install screen
# 創建一個名爲test的會話窗口
screen -S test
# 暫離窗口
Ctrl+a d(即按住Ctrl,依次再按a,d)
# 查看存在的會話窗口
screen -ls
# 進入窗口
screen -r test
screen -r 進程ID
# 關閉窗口
exit
# 窗口切換
Ctrl+a c :在當前screen會話中創建窗口
Ctrl+a w :窗口列表
Ctrl+a n :下一個窗口
Ctrl+a p :上一個窗口
Ctrl+a 0-9 :在第0個窗口和第9個窗口之間切換

有了 screen 工具,我們就可以在終端上創建窗口,然後運行需要的命令,然後暫離,然後就可以繼續做其他的事情了,當然,也可以用其他的終端連接服務器後使用screen -r命令連接需要的窗口,會發現程序一直在運行,退出終端也不會影響到那些暫離的終端上運行的程序。

測試

我們寫一個測試腳本test.sh

#!/bin/sh
for ((i=1; i<1000; i++))
do
    d=`date '+%Y-%m-%d %H:%M:%S'`
    echo "$d 第 $i 次輸出;"
    tt
    sleep 2s
done

只使用&後臺運行:

[root@localhost test.cc]# ./test.sh > test.log 2>&1 &
[1] 15037
[root@localhost test.cc]# ps -aux | grep test.sh
root     15037  0.0  0.0 113180  1424 pts/0    S    16:10   0:00 /bin/sh ./test.sh
root     15045  0.0  0.0 112712   992 pts/0    S+   16:10   0:00 grep --color=auto test.sh

可以看到15037進程在運行;

如果直接關閉終端,日誌記錄就停止了,說明進程隨着終端會話的結束而停止執行了;

但是,經過反覆測試發現,如果使用exit命令正常退出終端,再連上終端後,使用&運行的程序繼續在運行,也就是&命令跟nohup效果是一樣的,我這裏使用的測試環境是CentOS7.6。

使用nohup & 運行

[root@localhost test.cc]# nohup ./test.sh > test.log 2>&1 &
[1] 14349

測試結果,直接關閉終端或者使用exit命令退出終端,程序都會繼續執行。

說明⚠️:

我在使用阿里雲nas做測試時,使用 nohup & 這種方法執行命令後,直接關閉終端,程序會結束的!這點請大家注意~

使用screen運行

# 創建窗口
screen -S test
# 運行命令,這裏可以不用後面的&,只是程序會把窗口占用
./test.sh > test.log 2>&1 &
# 暫離
Ctrl + a d

這時候可以直接關閉終端了,然後重新連接,發現程序依然在運行,如果要找到窗口連接:

# 存在的窗口
[root@localhost ~]# screen -ls
There is a screen on:
    18048.test  (Detached)
1 Socket in /var/run/screen/S-root.
# 進入窗口
[root@localhost ~]# screen -r test

進入之後會發現,窗口依然保持着暫離之前的狀態,包括之前輸入的程序和命令,當你在窗口中輸入exit命令退出窗口,如果你前面命令後面沒有使用&,程序將會中止,因爲相對於test窗口來說,這是一個前臺程序,窗口退出了程序自然就跟着中止了。

因爲screen的暫離功能,可以實現暫離窗口中保持前臺程序的繼續運行,相對於真正的終端而言,就相當於後臺運行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章