zoukankan      html  css  js  c++  java
  • 后台运行程序的几种方式

    目录

    参考: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

    注:这部分内容,未测试过,完全摘抄2008 年的原文:https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/

    $ 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 -list
    There 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 9499
    init─┬─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 9488
    init─┬─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>作为屏幕命令。

  • 相关阅读:
    大型网站的数据库分割问题。
    大型网站的数据库分割问题。
    分布式集群的Session问题
    大型网站架构设计摘要
    大型网站的架构概要
    公司产品的优势
    java.util.concurrent 学习笔记(2) 线程池基础
    《Java 7 并发编程指南》学习概要 (6) Fork/Join
    《Java 7 并发编程指南》学习概要 (5) 线程池
    《Java 7 并发编程指南》学习概要 (4) 并发集合
  • 原文地址:https://www.cnblogs.com/sztom/p/10756014.html
Copyright © 2011-2022 走看看