實現關閉ssh繼續執行程式 tmux

2021-06-29 03:43:52 字數 3752 閱讀 8115

問題1:為什麼ssh一關閉,程式就不再執行了

元凶:sighup 訊號

讓我們來看看為什麼關掉視窗/斷開連線會使得正在執行的程式死掉。

在linux/unix中,有這樣幾個概念:

程序組(process group):乙個或多個程序的集合,每乙個程序組有唯一乙個程序組id,即程序組長程序的id。

會話期(session):乙個或多個程序組的集合,有唯一乙個會話期首程序(session leader)。會話期id為首程序的id。

會話期可以有乙個單獨的控制終端(controlling terminal)。與控制終端連線的會話期首程序叫做控制程序(controlling process)。當前與終端互動的程序稱為前台程序組。其餘程序組稱為後台程序組。

根據posix.1定義:

結束通話訊號(sighup)預設的動作是終止程式。

當終端介面檢測到網路連線斷開,將結束通話訊號傳送給控制程序(會話期首程序)。

如果會話期首程序終止,則該訊號傳送到該會話期前台程序組。

乙個程序退出導致乙個孤兒程序組中產生時,如果任意乙個孤兒程序組程序處於stop狀態,傳送sighup和sigcont訊號到該程序組中所有程序。

結論:因此當網路斷開或終端視窗關閉後,也就是ssh斷開以後,控制程序收到sighup訊號退出,會導致該會話期內其他程序退出。

例子:

我們來看乙個例子。開啟兩個ssh終端視窗,在其中乙個執行top命令。

在另乙個終端視窗,找到top的程序id為12912,父程序id為12825,即登陸shell

使用pstree命令可以更清楚地看到這個關係:

使用ps-xj命令可以看到,登入shell(pid 12912)和top在同乙個會話期,shell為會話期首程序,所在程序組pgid為12825,top所在程序組pgid為12912,為前台程序組。

關閉第乙個ssh視窗,在另乙個視窗中可以​​看到top也被殺掉了。

問題2:為什麼守護程序就算ssh開啟的,就算關閉ssh也不會影響其執行?

因為他們的程式特殊,比如

執行這個以後,他不屬於sshd這個程序組 而是單獨的程序組,所以就算關閉了ssh,和他也沒有任何關係!!

結論:守護程序的啟動命令本身就是特殊的,和一般命令不同的

比如mysqld_safe 這樣的命令 一旦使用了 就是守護程序執行

所以想把一般程式改造為守護程式是不可能的

問題3 使用後台執行命令& 能否將程式擺脫ssh?

我們做乙個實驗:

利用ctrl+d 登出以後 再進入系統 會不會看見這個命令再執行?

答案是 :命令被中止了!!

因為他依然屬於這個ssh程序組 就算加了&也無法擺脫!!

問題4 nohup能解決的問題

但是為了能夠再登出以後 依然能後台執行,那麼我們就可以使用nohup這個命令,我們現在開始查詢find / -name 『http』 &

,並且希望在後台能夠定期執行,

那麼就使用nohup:

嗯,證明執行成功,同時把程式執行的輸出資訊放到當前資料夾的 nohup.out 檔案中去。

然後我們馬上退出

再進去 開啟vim nohup.out 果然資訊都在

那麼現在我執行乙個比較長的搜尋:

再退出 再進去 開啟vim nohup.out 發現 原來 是預設迭加再後面得 資訊 看看 的確 執行了:

加不加&並不會影響這個命令 只是讓程式 前台或者後台執行而已

可以使用tmux或者screen來保證ssh斷開之後能繼續執行程式,

我個人推薦使用tmux,因為screen的子介面和父介面沒有任何不同,很容易出錯。但是tmux不一樣,在子介面中執行tmux只有會丟擲錯誤資訊:

而且tmux還能實現分屏功能:

以下是我的.tmux.conf:

unbind c-b 

set -g prefix c-a

setw -g mode-keys vi

set -g default-terminal "screen-256color"

# use 256 colors

set -g display-time

5000

# status line messages display

set -g status-utf8 on # enable utf-8

set -g history-limit 100000

# scrollback buffer n lines

# split window like vim

# vim's defination of a horizontal/vertical split is revised from tumx's

unbind %

bind

ssplit-window -h

unbind '"'

bind v split-window -v

# move arount panes wiht hjkl, as one would in vim after c-w

bind h select-pane -l

bind j select-pane -d

bind k select-pane -u

bind l select-pane -r

# copy and paste like in vim

unbind [

bind escape copy-mode

unbind p

bind p paste-buffer

bind -t vi-copy 'v' begin-selection

bind -t vi-copy 'y' copy-selection

# highlight active window

setw -g window-status-current-bg red

# open remind

setw -g monitor-activity on

set -g visual-activity on

關閉 go 後台執行程式

第一種 先檢視埠占用情況,然後kill 9 比如監控的是8000埠 lsof i 8000 或加個tcp查詢tcp服務 lsof i tcp 8080 找到對應的埠後kill掉 kill 9 900 第二種 killall 程式名稱 第三種 使用supervisor管理 其他方法參考 第四種 如果h...

SSH斷開後讓程式繼續執行

shell支援作用控制,有以下命令 command 讓程序在後台執行 jobs 檢視當前在後台執行的程序 fg n 讓後台執行的程序n到前台來,這裡的n為job number,不是pid bg n 讓程序n到後台去,或讓後台暫停的程序繼續執行,n同上 ctrl z 將乙個正在前台執行的命令放到後台,...

C 檢視系統正在執行的程式,並關閉執行程式

using system.diagnostics 第一種方法 richtextbox1.text string.empty 清空控制項 process myprocesses process.getprocesses 獲取當前程序陣列 foreach process myprocess in myp...