1. 程式人生 > >後臺運行程序的幾種方式

後臺運行程序的幾種方式

char cut lis rom exe 命令 文件中 重新 hang

目錄

1. 當前終端後臺運行
示例1,使用ctrl z, bg
示例2,使用&
示例3,重定向標準輸出和標準錯誤輸出
2. 脫離當前終端運行
示例4,使用nohup,忽略掛起,避免終端關閉導致程序也被關閉。
示例5,使用setsid,使程序直接運作在init下(即父進程為1),自然不會受到當前終端的影響了。
示例6,使用disown
3. 偽終端下運行
示例7,使用screen

參考:https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html

1. 當前終端後臺運行

示例1,使用ctrlz, bg

$ mate-system-monitor
//運行中,終端被占用;使用快捷鍵 [ctrl z] 暫停運行,返回終端
job1, ‘mate-system-monitor‘ has stopped

$ jobs //查看後臺運行程序,有這個狀態為停止的後臺程序
Job Group CPU State Command
1 7870 0% stopped mate-system-monitor

$ bg %1 //在後臺繼續運行程序
Send job 1 “mate-system-monitor” to background

$ jobs //查看,狀態已變為運行了

Job Group CPU State Command
1 7870 0% running mate-system-monitor

$ fg %1 //將後臺程序返回到前臺,
Send job 1, “mate-system-monitor” to foreground

// [ctrl c] //終止程序

示例2,使用&

$ mate-system-monitor &
$ jobs -l
Job Group CPU State Command
1 10084 4% running mate-system-monitor

$ mate-system-monitor & //相當與如下3個步驟:

  • $ mate-system-monitor
  • [ctrl z]
  • $ bg %1

示例3,重定向標準輸出和標準錯誤輸出

當後臺運行程序有輸出時,會擾亂當前終端的內容。可用">filename 2>&1"來更改缺省的重定向文件名。

$ mate-system-monitor > mate-system-monitor_log.txt 2>&1 &
$ jobs
Job Group CPU State Command
1 10565 22% running mate-system-monitor > mate-system-monitor_log.txt 2>&1 &

這樣終端就不會收到幹擾了。

$ sslocal -c s.json > sw_log 2>&1 &
$ jobs
Job Group CPU State Command
2 10880 12% running sslocal -c s.json > sw_log 2>&1 &
1 10565 11% running mate-system-monitor > mate-system-monitor_log.txt 2>&1 &

以上都是在某個終端執行,父進程都是終端。若父進程關閉,則會關閉下面所有子進程。

2. 脫離當前終端運行

示例4,使用nohup, 忽略掛起,避免終端關閉導致程序也被關閉。

nohup (no hangup 不掛起)放在命令的前面; 標準輸出和標準錯誤缺省會被重定向到nohup.out 文件中。
一般我們可在結尾加上"&"來將命令同時放入後臺運行,也可用">filename 2>&1"來更改缺省的重定向文件名。

$ nohup mate-system-monitor > mate-system-monitor_log.txt 2>&1 &
$ jobs
Job Group CPU State Command
1 11164 2% running nohup mate-system-monitor > mate-system-monitor_log.txt 2>&1 &

$ exit //要退出終端會提示
There are still jobs active:
PID Command
12086 nohup mate-system-monitor > mate-system-monitor_log.txt 2>&1 &
A second attempt to exit will terminate them.
Use ‘disown PID‘ to remove jobs from the list without terminating them.

若強行關閉後,上面進程的父進程由原本的bash的pid變為1。

示例5,使用setsid, 使程序直接運作在init下(即父進程為1),自然不會受到當前終端的影響了。

setsid setsid(8) run a program in a new session

$ setsid mate-system-monitor > mate-system-monitor_log.txt 2>&1 &
$ jobs
jobs: There are no jobs
Job 1, ‘setsid mate-system-monitor > ma…‘ has ended
$ jobs
jobs: There are no jobs

父進程直接就是1了,jobs也看不到了,只能通過ps等查找了。
$ ps -ef |grep mate-system-monitor
toma 12799 12546 1 08:04 pts/1 00:00:14 mate-system-monitor
toma 13758 12546 0 08:18 pts/1 00:00:00 grep --color=auto mate-system-monitor

示例6,使用disown

若運行命令時未加nohup 或者setsid,可用disown補救,
$ mate-system-monitor > mate-system-monitor_log.txt 2>&1 &
$ jobs
Job Group CPU State Command
1 14318 9% running mate-system-monitor > mate-system-monitor_log.txt 2>&1 &
$ disown %1
$ jobs
jobs: There are no jobs

$ ps -ef |grep mate-system-monitor
toma 14318 12546 1 08:24 pts/1 00:00:25 mate-system-monitor
toma 16098 12546 0 08:51 pts/1 00:00:00 grep --color=auto mate-system-monitor
父進程變為1,已脫離當前的終端。
以上命令實現在後臺運行,還脫離了當前終端的影響,但是無法再重新連接到這個會話。

3. 偽終端下運行

示例7,使用screen

https://wiki.archlinux.org/index.php/GNU_Screen
$ sudo pacman -Ss screen
extra/screen 4.6.2-1
Full-screen window manager that multiplexes a physical terminal
簡單的說,screen 提供了ANSI/VT100 的終端模擬器,使它能夠在一個真實終端下運行多個全屏的偽終端。screen命令提供了分離和重新連接一個會話的功能。
常用選項:


用screen -dmS session name來建立一個處於斷開模式下的會話(並指定其會話名)。
用screen -list 來列出所有會話。
用screen -r session name來重新連接指定會話。
用快捷鍵CTRL-a d 來暫時斷開當前會話。











-4 Resolve hostnames only to IPv4 addresses. 僅將主機名解析為IPv4地址。
-6 Resolve hostnames only to IPv6 addresses. 僅將主機名解析為IPv6地址。
-a Force all capabilities into each window‘s termcap. 強制所有功能進入每個窗口的termcap。
-A -[r|R] Adapt all windows to the new display width & height. 使所有窗口適應新的顯示寬度和高度。
-c file Read configuration file instead of ‘.screenrc‘. 讀取配置文件而不是“.screenrc”。
-d (-r) Detach the elsewhere running screen (and reattach here). 分離其他正在運行的屏幕(並重新連接到此處)。
-dmS name Start as daemon: Screen session in detached mode. 作為守護程序啟動:處於分離模式的屏幕會話。
-D (-r) Detach and logout remote (and reattach here). 分離並註銷遠程(並在此處重新連接)。
-D -RR Do whatever is needed to get a screen session. 做任何需要的屏幕會話。
-e xy Change command characters. 更改命令字符。
-f Flow control on, -fn = off, -fa = auto. 流量控制開啟,-fn =關閉,-fa = auto。
-h lines Set the size of the scrollback history buffer. 設置回滾歷史記錄緩沖區的大小。
-i Interrupt output sooner when flow control is on. 當流量控制打開時,中斷輸出更快。
-l Login mode on (update /var/run/utmp), -ln = off. 登錄模式開啟(更新/ var / run / utmp), - ln =關閉。
-ls [match] or 要麽
-list Do nothing, just list our SockDir [on possible matches]. 什麽都不做,只需列出我們的SockDir [在可能的比賽中]。
-L Turn on output logging. 打開輸出記錄。
-Logfile file Set logfile name. 設置日誌文件名稱。
-m ignore $STY variable, do create a new screen session. 忽略$ STY變量,以創建新的屏幕會話。
-O Choose optimal output rather than exact vt100 emulation. 選擇最佳輸出而不是精確的vt100仿真。
-p window Preselect the named window if it exists. 如果存在,則預選指定的窗口。
-q Quiet startup. Exits with non-zero return code if unsuccessful. 安靜的啟動。如果不成功,則退出非零返回碼。
-Q Commands will send the response to the stdout of the querying process. 命令會將響應發送到查詢過程的標準輸出。
-r [session] Reattach to a detached screen process. 重新連接到分離的屏幕進程。
-R Reattach if possible, otherwise start a new session. 如果可能,重新連接,否則,開始新的會話。
-s shell Shell to execute rather than $SHELL. Shell執行而不是$ SHELL。
-S sockname Name this session <pid>.sockname instead of <pid>.<tty>.<host>. 將此會話命名為<pid> .sockname而不是<pid>。<tty>。<host>。
-t title Set title. (window‘s name). 設置標題。 (窗口的名字)。
-T term Use term as $TERM for windows, rather than "screen". 使用術語作為Windows的$ TERM,而不是“屏幕”。
-U Tell screen to use UTF-8 encoding. 告訴屏幕使用UTF-8編碼。
-v Print "Screen version 4.06.02 (GNU) 23-Oct-17". 打印“屏幕版本4.06.02(GNU)23-Oct-17”。
-wipe [match] Do nothing, just clean up SockDir [on possible matches]. 什麽都不做,只是清理SockDir [在可能的比賽中]。
-x Attach to a not detached screen. (Multi display mode). 附加到未分離的屏幕。 (多顯示模式)。
-X Execute <cmd> as a screen command in the specified session. 在指定的會話中執行<cmd>作為屏幕命令。

後臺運行程序的幾種方式