目录
参考: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 Command1 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
注:这部分内容,未测试过,完全摘抄2008 年的原文:
$ 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 来暂时断开当前会话。screen 示例
[root@pvcent107 ~]# screen -dmS Urumchi[root@pvcent107 ~]# screen -listThere is a screen on: 12842.Urumchi (Detached)1 Socket in /tmp/screens/S-root.[root@pvcent107 ~]# screen -r Urumchi当我们用“-r”连接到 screen 会话后,我们就可以在这个伪终端里面为所欲为,再也不用担心 HUP 信号会对我们的进程造成影响,也不用给每个命令前都加上“nohup”或者“setsid”了。这是为什么呢?让我来看一下下面两个例子吧。1. 未使用 screen 时新进程的进程树
[root@pvcent107 ~]# ping www.google.com &[1] 9499[root@pvcent107 ~]# pstree -H 9499init─┬─Xvnc ├─acpid ├─atd ├─2*[sendmail] ├─sshd─┬─sshd───bash───pstree │ └─sshd───bash───ping我们可以看出,未使用 screen 时我们所处的 bash 是 sshd 的子进程,当 ssh 断开连接时,HUP 信号自然会影响到它下面的所有子进程(包括我们新建立的 ping 进程)。2. 使用了 screen 后新进程的进程树
[root@pvcent107 ~]# screen -r Urumchi[root@pvcent107 ~]# ping www.ibm.com &[1] 9488[root@pvcent107 ~]# pstree -H 9488init─┬─Xvnc ├─acpid ├─atd ├─screen───bash───ping ├─2*[sendmail]而使用了 screen 后就不同了,此时 bash 是 screen 的子进程,而 screen 是 init(PID为1)的子进程。那么当 ssh 断开连接时,HUP 信号自然不会影响到 screen 下面的子进程了。 =========https://wiki.archlinux.org/index.php/GNU_Screen -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>作为屏幕命令。