1. 程式人生 > >遠端連線Linux,如何使程式斷開連線後繼續執行

遠端連線Linux,如何使程式斷開連線後繼續執行

遠端連線到Linux終端後,如果發生意外或者人為斷開了遠端連線,那麼正在執行的程式或命令(例如備份資料庫這種比較耗時的操作)就會中斷。原因是因為斷開連線後,終端會收到SIGHUP(hang-up 結束通話)訊號從而關閉該會話期的子程序。

解決方法

1. nohup 命令

nohup命令的功能就和它的名字一樣,no hup,忽略hup訊號,不掛斷程序,程序仍然屬於當前會話(終端關閉後,程序會變成孤兒程序,PPID變成1)。
例如:(不加& 命令不會在後臺執行)

[root@localhost ~]# nohup ping 127.0.0.1 &
[1] 27641 nohup: 忽略輸入並把輸出追加到"nohup.out"
  • 1
  • 2
  • 3

nohup會將ping命令的預設輸出從螢幕重定向到當前目錄的nohup.out檔案,如果當前目錄不可寫,會重定向到 $HOME/nohup.out 。
如果ping命令已經重定向輸出了,就不會重定向到nohup.out了,例如nohup ping 127.0.0.1>/dev/null &

2. screen 命令

如果程式需要互動等複雜的操作,推薦使用功能強大的screen。screen 提供了 ANSI/VT100 的終端模擬器,使它能夠在一個真實終端下執行多個全屏的偽終端。
不是所有Linux都自帶screen。查詢安裝包資訊:rpm -qa|grep screen


安裝方法:

  • CentOS系統:yum install screen
  • Debian 系統:apt-get install screen

用法:

  • 開啟新的會話視窗:screen
  • 結束當前會話:exit
  • 在新會話中執行程式(程式關閉時會話自動結束):screen vi test.c
  • 開啟新會話並起個名字:screen -S myname
  • 暫時離開會話(經常用):Ctrl+a 然後 d
  • 檢視會話列表: screen -ls
  • 恢復之前離開的會話:screen -r 會話名或程序號
  • 清除dead狀態的會話:screen -wipe
  • 啟動一個開始就是Detached狀態的會話:screen -dmS 名字 命令
常用快捷鍵 功能
Ctrl+a ? 顯示所有鍵繫結資訊
Ctrl+a d 暫時離開會話返回之前的shell(會話進入Detached狀態)
Ctrl+a w 顯示所有視窗列表(不包括Detached狀態的)
Ctrl+a Ctrl+a 切換到之前顯示的視窗(不切換Detached狀態的)
Ctrl+a c 建立一個新的執行shell的視窗並切換到該視窗
Ctrl+a n 切換到下一個視窗
Ctrl+a p 切換到上一個視窗
Ctrl+a 0..9 切換到視窗0..9
Ctrl+a k 殺掉當前視窗(會提示確認)

參考:
http://www.path8.net/tn/archives/3746
http://blog.csdn.net/v1v1wang/article/details/6855552

程序操作相關的命令

1. &

舉例:ping 127.0.0.1 >/dev/null 2>&1 &
後臺執行ping命令(終端不顯示輸出結果和錯誤資訊),關閉終端會終止命令。

2. Ctrl+C、 Ctrl+Z

Ctrl+C 終止當前命令
Ctrl+Z 掛起當前命令到後臺,命令會暫停執行

[[email protected] ~]# ping 127.0.0.1>/dev/null
^Z
[1]+  Stopped                 ping 127.0.0.1 > /dev/null
  
  • 1
  • 2
  • 3

3. jobs、 fg、 bg

jobs 顯示當前會話執行的後臺任務
語法:jobs [-lnprs] [jobspec ...] or jobs -x command [args]
引數:

  • -l 比預設多顯示程序id(PID),+表示當前任務,-表示非當前,任務有4種狀態:running、stopped、done(正常完成)、Terminated(中止,比如通過kill命令殺死)
  • -p 僅顯示程序號
  • -n 顯示任務狀態的變化 (然而我沒有試出效果)
  • -r 僅顯示執行狀態(running)的任務;
  • -s 僅顯示停止狀態(stoped)的任務。r s兩個引數一起用只有放在後面的會起作用。
  • jobspec 表示任務號或唯一的任務名,可以多個。
[root@localhost ~]# jobs
[1]-  Running                 ping 127.0.0.1 > /dev/null &
[2]+  Stopped                 vi
[root@localhost ~]# jobs -l
[1]- 21777 Running            ping 127.0.0.1 > /dev/null &
[2]+ 21778 停止 (tty 輸出)     vi
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

fg 將後臺任務放到前臺(Foreground)
語法:fg [job_spec] 不加引數表示操作當前任務
bf 使掛起的任務在後臺執行(Background )
語法:bg [job_spec ...] 不加引數表示操作當前任務

[root@localhost ~]# ping 127.0.0.1>/dev/null
^Z
[1]+  Stopped                 ping 127.0.0.1 > /dev/null
[root@localhost ~]# bg 1
[1]+ ping 127.0.0.1 > /dev/null &
[root@localhost ~]# jobs
[1]+  Running                 ping 127.0.0.1 > /dev/null &
[root@localhost ~]# fg
ping 127.0.0.1 > /dev/null
^C
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4. ps、 pstree

ps 檢視系統程序
預設值顯示當前會話的程序:

[root@localhost ~]# ps
  PID TTY          TIME CMD
27850 pts/2    00:00:00 bash
28304 pts/2    00:00:00 ps
  
  • 1
  • 2
  • 3
  • 4

ps -ef 完整格式顯示所有程序。PID是程序號,PPID是父程序號
可以用管道符 | 聯合grep過濾輸出:

[root@localhost ~]# ps -ef|grep SCREEN
root     28364 27850  0 18:03 pts/2    00:00:00 grep SCREEN
root     28825     1  0 Oct09 ?        00:00:00 SCREEN -S mym
  
  • 1
  • 2
  • 3

pstree 顯示程序樹

  • pstree 顯示完整程序樹,根節點為init
  • pstree 程序ID 以指定程序為根顯示程序樹
  • pstree -h 特別標明現在執行的程式。
  • pstree -H程序ID 但特別標明指定的程式
  • pstree -a 顯示每個程式的完整指令,包含路徑,引數或是常駐服務的標示

5. kill、 pkill

kill 傳送訊號給系統,讓系統將指定程序結束

  • kill -l 顯示訊號列表,常用的有2個,SIGTERM 代號15(預設訊號),SIGKILL 代號 9
  • kill 程序ID 傳送SIGTERM,程式可以花一段時間正常關閉自己,該訊號可以被忽略。
  • kill -15 %jobspec 正常結束任務
  • kill -9 程序ID 傳送SIGKILL ,強制結束程式,未儲存的進度將會丟失,程式不能忽略此訊號。
  • kill -9 %jobspec 強制結束任務

pkill 通過命令名字結束程序,可以使用正則。訊號值和kill一樣

  • pkill -9 fire 請求強制結束所有名字中有fire的程序
    為了避免匹配錯,可以先使用pgrep -l fire或者ps -ef|grep fire查詢一下
  • pkill -u 使用者列表 正常結束指定使用者下的所有程序
  • pkill -P PPID列表 正常結束指定父程序下的所有程序

遠端連線到Linux終端後,如果發生意外或者人為斷開了遠端連線,那麼正在執行的程式或命令(例如備份資料庫這種比較耗時的操作)就會中斷。原因是因為斷開連線後,終端會收到SIGHUP(hang-up 結束通話)訊號從而關閉該會話期的子程序。