問題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...