【OS】Linux命令如何放到后台运行

【OS】Linux命令如何放到后台运行
php



linux命令后台运行

   有两种方式:mysql


   1. command & : 后台运行,你关掉终端会中止运行    linux

   2. nohup command & : 后台运行,你关掉终端也会继续运行    sql


   


1、 简介          shell

    Linux/Unix 区别于微软平台最大的优势就是真正的多用户,多任务。所以在任务管理上也有别具特点的管理思想。      windows

咱们知道,在 Windows 上面,咱们要么让一个程序做为服务在后台一直运行,要么中止这个服务。而不能让程序在前台后台之间切换。而 Linux 提供了 fg 和bg 命令,让你轻松调度正在运行的任务。假设你发现前台运行的一个程序须要很长的时间,可是须要干其余的事情,你就能够用 Ctrl-Z ,挂起这个程序,而后能够看到系统提示:      bash

[1]+ Stopped /root/bin/rsync.sh      服务器

而后咱们能够把程序调度到后台执行:(bg 后面的数字为做业号)      网络

 

#bg 1   session

     

[1]+ /root/bin/rsync.sh &      

用 jobs 命令查看正在运行的任务:      

 

#jobs   

     

[1]+ Running /root/bin/rsync.sh &      

若是想把它调回到前台运行,能够用      

 

#fg 1   

     

/root/bin/rsync.sh      

这样,你在控制台上就只能等待这个任务完成了。      



&    将指令丢到后台中去执行      

 

[ctrl]+z 將前台任务丟到后台中暂停   

    

jobs 查看后台的工做状态   

    

fg %jobnumber 将后台的任务拿到前台来处理   

    

bg %jobnumber 将任务放到后台中去处理   

    

kill 管理后台的任务   

     


2、&

在Linux中,当在前台运行某个做业时,终端被该做业占据;而在后台运行做业时,它不会占据终端。可使用&命令把做业放到后台执行。实际上,这样是将命令放入到一个做业队列中了:


$ ./test.sh &      

[1] 17208      



$ jobs -l      

[1]+ 17208 Running                 ./test.sh &      

    在后台运行做业时要小心:须要用户交互的命令不要放在后台执行,由于这样你的机器就会在那里傻等。不过,做业在后台运行同样会将结果输出到屏幕上,干扰你的工做。若是放在后台运行的做业会产生大量的输出,最好使用下面的方法把它的输出重定向到某个文件中:      

 

command >out.file 2>&1 &      

在上面的例子中,   2>&1   表示全部的标准输出和错误输出都将被重定向到一个叫作out.file 的文件中。 当你成功地提交进程之后,就会显示出一个进程号,能够用它来监控该进程,或杀死它。       

例:查找名为“httpd.conf”的文件,并把全部标准输出和错误输出重定向到find.dt的文件中:       

 

# find /etc/httpd/ -name "httpd.conf" -print >find.dt 2>&1 &       

[2] 7832       

成功提交该命令以后,系统给出了它的进程号7832。 对于已经在前台执行的命令,也能够从新放到后台执行,首先按ctrl+z暂停已经运行的进程,而后使用bg命令将中止的做业放到后台运行,例如对正在前台执行的tesh.sh使用ctrl+z挂起它:      

$ ./test.sh      

[1]+ Stopped                 ./test.sh      



$ bg %1      

[1]+ ./test.sh &      



$ jobs -l      

[1]+ 22794 Running                 ./test.sh &      


可是如上方到后台执行的进程,其父进程仍是当前终端shell的进程,而一旦父进程退出,则会发送hangup信号给全部子进程,子进程收到hangup之后也会退出。若是咱们要在退出shell的时候继续运行进程,则须要使用nohup忽略hangup信号,或者setsid将将父进程设为init进程(进程号为1)


$ echo $$      

21734      



$ nohup ./test.sh &      

[1] 29016      



$ ps -ef | grep test      

515      29710 21734 0 11:47 pts/12   00:00:00 /bin/sh ./test.sh      

515      29713 21734 0 11:47 pts/12   00:00:00 grep test      

$ setsid ./test.sh &      

[1] 409      



$ ps -ef | grep test      

515        410     1 0 11:49 ?        00:00:00 /bin/sh ./test.sh      

515        413 21734 0 11:49 pts/12   00:00:00 grep test      

上面的试验演示了使用nohup/setsid加上&使进程在后台运行,同时不受当前shell退出的影响。那么对于已经在后台运行的进程,该怎么办呢?可使用disown命令:      



$ ./test.sh &      

[1] 2539      



$ jobs -l      

[1]+ 2539 Running                 ./test.sh &      


$ disown -h %1


$ ps -ef | grep test      

515        410     1 0 11:49 ?        00:00:00 /bin/sh ./test.sh      

515       2542 21734 0 11:52 pts/12   00:00:00 grep test      

另外还有一种方法,即便将进程在一个subshell中执行,其实这和setsid殊途同归。方法很简单,将命令用括号() 括起来便可:      


$ (./test.sh &)


$ ps -ef | grep test      

515        410     1 0 11:49 ?        00:00:00 /bin/sh ./test.sh      

515      12483 21734 0 11:59 pts/12   00:00:00 grep test      

注:本文试验环境为Red Hat Enterprise Linux AS release 4 (Nahant Update 5),shell为/bin/bash,不一样的OS和shell可能命令有些不同。例如AIX的ksh,没有disown,可是可使用nohup -p PID来得到disown一样的效果。      


还有一种更增强大的方式是使用screen,首先建立一个断开模式的虚拟终端,而后用-r选项从新链接这个虚拟终端,在其中执行的任何命令,都能达到nohup的效果,这在有多个命令须要在后台连续执行的时候比较方便:

$ screen -dmS screen_test


$ screen -list      

There is a screen on:      

        27963.screen_test       (Detached)      

1 Socket in /tmp/uscreens/S-jiangfeng.      


$ screen -r screen_test


3、 nohup       

    若是你正在运行一个进程,并且你以为在退出账户时该进程还不会结束,那么可使用nohup命令。该命令能够在你退出账户以后继续运行相应的进程。nohup就是不挂起的意思( no hang up)。 该命令的通常形式为:       

 

nohup conmmand &      

若是使用nohup命令提交做业,那么在缺省状况下该做业的全部输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:      

 

nohup command > myout.file 2>&1       

在上面的例子中,输出被重定向到myout.file文件中。      




     

 

4、.*,?,[...],[!...]等    

    

下面就是这些特殊字符:       

 

* 匹配文件名中的任何字符串,包括空字符串。       

 

? 匹配文件名中的任何单个字符。       

 

[...] 匹配[ ]中所包含的任何字符。       

 

[!...] 匹配[ ]中非感叹号!以后的字符。       

 

当s h e l l遇到上述字符时,就会把它们看成特殊字符,而不是文件名中的普通字符,这样用户就能够用它们来匹配相应的文件名。      


 

1)列出以i或o开头的文件名:     #ls [io]*      

 

2)列出log.开头、后面跟随一个数字、而后能够是任意字符串的文件名: #ls log.[0-9]*       

 

3)与例二相反,列出log.开头、后面不跟随一个数字、而后能够是任意字符串的文件名 : #ls log.[!0-9]*       

 

4)列出全部以LPS开头、中间能够是任何两个字符,最后以1结尾的文件名:#ls LPS??1      

 

5)列出全部以大写字母开头的文件名:$ ls [A-Z]* 6)列出全部以. 开头的文件名(隐含文件,例如. profile、.rhosts、.histo ry等): $ ls .*      


  • 其余相关命令:


jobs  :查看当前有多少在后台运行的命令    

fg  :将后台中的命令调至前台继续运行。若是后台中有多个命令,能够用 fg %jobnumber将选中的命令调出,%jobnumber是经过jobs命令查到的后台正在执行的命令的序号(不是pid)    

bg  :将一个在后台暂停的命令,变成继续执行。若是后台中有多个命令,能够用bg %jobnumber将选中的命令调出,%jobnumber是经过jobs命令查到的后台正在执行的命令的序号(不是pid)    


  • 杀死进程

杀死已经启动的程序和普通方式同样:

  • pkill -9 name
  • killall name
  • kill pid

 

 




執行背景工做的指令

指令或符號

使用範例

說明

& % fasta & 在背景中執行程式
jobs % jobs 顯示送入背景之工做
kill % kill (job#) 移除指定之批次工做
ctrl-z   暫停前景中執行之程式
bg % bg 將暫停之工做送入背景執行
fg % fg 將背景之工做拉回前景執行



1.经过使用‘&’操做符让Job在后台运行
一般咱们Linux的终端中,运行某一命令时,终端老是等待某一特定的命令或程序运行完之后,给出一个提示,而后咱们才能继续运行下一个命令。若是咱们要运行一个比较耗时的命令,可是在该命令运行的同时还须要作另外的一些事,那该怎么办呢?
你能够经过在命令的后面加上一个‘&’操做符,来让一个任务在后台运行。(固然若是你是用GUI界面,你也能够从新打开一个窗口运行新的命令或程序)
例如,咱们须要拷贝一个比较大的文件,在拷贝的同时,还要作其余一些事情,那么在拷贝命令后面加上一个‘&’,让它在后台拷贝:
lennon@lennon-laptop:~$ cp /media/bigfile /home/lennon/Downloads/ &
[1] 3526
lennon@lennon-laptop:~$ 
此时,咱们能够看到在终端中,执行了某一命令后,给出了一些信息,而后就返回了,接着提示用户能够出入下一个命令了,这样程序或命令就在后台执行了。
在显示的信息中,用方括号括起来的数字,表示系统分配给这个Job的Job Number,这里'[1]'中的1,就是这个Job的Job Number。然后面一个比较大的数字,则是系统分配的进程ID(PID),这个PID在系统就表明这个进程。
在后台运行的job,当其运行完成之后,且输入回车后,会在终端中给出一个提示:
lennon@lennon-laptop:~$ rm Downloads/linux_11gR2_database_1of2.zip &
[1] 3666
lennon@lennon-laptop:~$ 
[1]+  Done                    rm Downloads/linux_11gR2_database_1of2.zip

2.使用jobs命令,来查看当前系统中的Job
若是咱们须要查看当前系统中,有那些job,使用‘jobs’命令:
lennon@lennon-laptop:~$ jobs
[1]-  Running                 cp /media/bigfile /home/lennon/Downloads/ &
[2]+  Stopped                 cat
lennon@lennon-laptop:~$ 
如此时,显示个人系统中有2个job,一个是刚才的正在运行的拷贝命令([1]标识),一个是中止运行的cat命令([2]表示)。这里‘Running’、‘Stopped’表示任务的状态。

jobs命令参考
命令名称:jobs
使用权限:全部权限
命令描述:列出系统中的job。注意:不是全部的shell都能使用此命令
语法:jobs [-p | -l] [-n] [-p] [-x] [job id]
参数:
-p | -l : Report the process group ID and working directory of the jobs.
-n      : Display only jobs that have stopped or exited since last notified.
-p      : Displays only the process IDs for the process group leaders of the selected jobs.
-x      : Replace any job_id found in command or arguments with the corresponding 
           process group ID, and then execute command passing it arguments.
job id  : The job id.

3.Suspend key 和 bg命令的使用(将一个正在运行的job放到后台运行)
若是你在运行job前,并不知道该job的运行状况,但在job运行了之后,发现这个是耗时的任务,并想将其放入到后台运行,这样你能够在这个任务运行的同时,完成一些其余的事情,那么你能够这样作:
使用挂起键(Suspend Key,一般是Ctrl-Z)将该任务挂起(也就是暂停),而后使用‘bg’命令在后台让该job恢复执行。
lennon@lennon-laptop:~$ cp bigfile bigfile.bac
^Z
[1]+  Stopped                 cp bigfile bigfile.bac
lennon@lennon-laptop:~$ bg %1
[1]+ cp bigfile bigfile.bac &
lennon@lennon-laptop:~$
使用Ctrl-Z后,系统会将当前正在运行的job暂停,将其移至后台,给出用户改任务的提示(包括job number、状态、job),而后提示用户输入下一个命令。
在job挂起后,可使用‘bg’命令,让job恢复到刚才中断的地方继续运行并将其放到后台运行。使用‘bg %job number’来指定你须要对哪个job进行操做,这里‘%’告诉系统后面的数字是一个job number(不要‘%’可能也能够)。固然在系统中只有一个job的时候,你也能够忽略改参数。

bg命令参考:
命令名称:bg
使用权限:全部权限
命令描述:在后台恢复已中止的job继续运行。注意该命令不能在全部的Unix的shell下运行
语法:bg [-l] [-p] [-x] [job]
参数:
-l    : Report the process group ID and working directory of the jobs.
-p    : Report only the process group ID of the jobs.
-x    : Replace any job_id found in command or arguments with the corresponding process  
         group ID, and then execute command passing it arguments.
job   : Specifies the job that you want to run in the background.

4.使用fg命令,将在后台的job换到前台
当你须要将在后台的job换到前台时,使用‘fg %job number’命令(也许不要‘%’也能够)。
lennon@lennon-laptop:~$ cp bigfile bigfile.bac &
[1] 3815
lennon@lennon-laptop:~$ fg 1
cp bigfile bigfile.bac

fg命令参考:
命令名称:fg
使用权限:全部权限
命令描述:将后台的任务移至前台,若是是该任务处于暂停状态,则恢复该任务的运行。
         注意该命令不是在全部的shell中都能运行。
语法:fg [%job]
参数:
%job : Specifies the job that you want to run in the foreground.

5.如何结束一个job
若是你想结束一个正在运行的job,可使用中断键(interrupt key,一般是Ctrl-C)来结束。
lennon@lennon-laptop:~$ cp bigfile bigfile.bac 
^C
lennon@lennon-laptop:~$ 
若是上面方法没法正常工做,那么你能够考虑使用Ctrl-Z(Suspend key)来暂停job,使用'jobs'命令来查看这个job的job number,而后经过'kill'命令来结束这个job.
lennon@lennon-laptop:~$ cp bigfile bigfile.bac 
^Z
[1]+  Stopped                 cp bigfile bigfile.bac
lennon@lennon-laptop:~$ jobs
[1]+  Stopped                 cp bigfile bigfile.bac
lennon@lennon-laptop:~$ kill %1
lennon@lennon-laptop:~$ 
[1]+  Terminated              cp bigfile bigfile.bac
'kill %1'中的'%'告诉系统,后面的数字是一个job number。默认状况下,kill将会向程序发送一个termination signal(-TERM)。若是这个信号不起做用,考虑使用'kill -kill %job number'来发送一个kill signal(-KILL)。
'kill'命令的使用,就看man把,info也能够,这里不说了,上面东西太多。不过经常使用的也就'kill %job number'、'kill -kill %job number'、'kill [-kill] PID'。


Linux下Ctrl-Z、Ctrl-C、Ctrl-D的具体含义
初识Linux,可能会对Ctrl-Z、Ctrl-C、Ctrl-D的具体含义混淆不清,由于这三个按键都可以在一些状况下使shell退出正在执行的命令或程序,提示用户输入下一个命令,从而对初识者形成假象,认为三个键的功能同样,但具体状况下哪一个按键能起做用、起什么做用却拿捏不定。

    Ctrl-Z:该键是linux下面默认的挂起键(Suspend Key),当键入Ctrl-Z时,系统会将正在运行的程序挂起,而后放到后台,同时给出用户相关的job信息。此时,程序并无真正的中止,用户能够经过使用fg、bg命令将job恢复到暂停前的上下文环境,并继续执行。
    Ctrl-C:该键是linux下面默认的中断键(Interrupt Key),当键入Ctrl-C时,系统会发送一个中断信号给正在运行的程序和shell。具体的响应结果会根据程序的不一样而不一样。一些程序在收到这个信号后,会当即结束并推出程序,一些程序可能会忽略这个中断信号,还有一些程序在接受到这个信号后,会采起一些其余的动做(Action)。当shell接受到这个中断信号的时候,它会返回到提示界面,并等待下一个命令。
    Ctrl-D:该键是Linux下面标准输入输出的EOF。在使用标准输入输出的设备中,遇到该符号,会认为读到了文件的末尾,所以结束输入或输出。




Linux下使Shell 命令脱离终端在后台运行

 (2012-02-05 21:41:57)

你是否遇到过这样的状况:从终端软件登陆远程的Linux主机,将一堆很大的文件压缩为一个.tar.gz文件,连续压缩了半个小时尚未完成,这时,忽然你断网了,你登陆不上远程Linux主机了,那么前面的半个小时就会前功尽弃,你很是气愤……

在Linux下,若是你要执行的shell命令耗时特别长,而且:(1)你的网络不稳定,随时可能断网;或者(2)你在执行了shell命令以后必需要关闭终端软件(例如SecureCRT)。


那么你就须要以脱离终端的方式在后台运行这个shell命令。

方法以下:

(1)输入命令:

nohup 你的shell命令 &

(2)回车,使终端回到shell命令行;

(3)输入exit命令退出终端:

exit

(4)如今能够关闭你的终端软件了,等过足够的时间,让你的shell命令执行完了再上去看结果吧。

其中,nohup命令可让你的shell命令忽略SIGHUP信号,便可以使之脱离终端运行;“&”可让你的命令在后台运行。

以脱离终端的方式在后台运行shell命令有这样几个好处:只要你执行过了命令,那么你的网络中断不会对你有任何影响,而且你就能够关闭终端软件了。

 

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文连接:http://www.linuxidc.com/Linux/2011-05/35723.htm

 

 

 

用运程终端登录Linux后运行的程序,当关闭终端时程序也被终至,下面的方法可让程序在后台运行。

Unix/Linux下通常好比想让某个程序在后台运行,不少都是使用 & 在程序结尾来让程序自动运行。好比咱们要运行mysql在后台:

  /usr/local/mysql/bin/mysqld_safe --user=mysql &

 可是加入咱们不少程序并不象mysqld同样作成守护进程,可能咱们的程序只是普通程序而已,通常这种程序使用 & 结尾,可是若是终端关闭,那么程序也会被关闭。可是为了可以后台运行,那么咱们就可使用nohup这个命令,好比咱们有个test.php须要在后台运行,而且但愿在后台可以按期运行,那么就使用nohup:

  nohup /root/test.php &

  提示:

  [~]$ appending output to nohup.out

  嗯,证实运行成功,同时把程序运行的输出信息放到当前目录的 nohup.out 文件中去。


附:nohup命令参考

  nohup 命令

  用途:不挂断地运行命令。

  语法:nohup Command [ Arg ... ] [ & ]

  描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略全部挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。

  不管是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。若是当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。若是没有文件能建立或打开以用于追加,那么 Command 参数指定的命令不可调用。若是标准错误是一个终端,那么把指定的命令写给标准错误的全部输出做为标准输出重定向到相同的文件描述符。

  退出状态:该命令返回下列出口值:

  126 能够查找但不能调用 Command 参数指定的命令。

  127 nohup 命令发生错误或不能查找由 Command 参数指定的命令。

  不然,nohup 命令的退出状态是 Command 参数指定命令的退出状态。


nohup命令及其输出文件

  nohup命令:若是你正在运行一个进程,并且你以为在退出账户时该进程还不会结束,那么可使用nohup命令。该命令能够在你退出账户/关闭终端以后继续运行相应的进程。nohup就是不挂起的意思( no hang up)。

  该命令的通常形式为:nohup command &


使用nohup命令提交做业

  若是使用nohup命令提交做业,那么在缺省状况下该做业的全部输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:

  nohup command > myout.file 2>&1 &

  在上面的例子中,输出被重定向到myout.file文件中。







Linux 技巧:让进程在后台可靠运行的几种方法



咱们常常会碰到这样的问题,用 telnet/ssh 登陆了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却因为网络的不稳定致使任务中途失败。如何让命令提交后不受本地关闭终端窗口/网络断开链接的干扰呢?下面举了一些例子, 您能够针对不一样的场景选择不一样的方式来处理这个问题。


nohup/setsid/&

场景:

若是只是临时有一个命令须要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?

hangup 名称的来由

在 Unix 的早期版本中,每一个终端都会经过 modem 和系统通信。当用户 logout 时,modem 就会挂断(hang up)电话。 同理,当 modem 断开链接时,就会给终端发送 hangup 信号来通知其关闭全部子进程。

解决方法:

咱们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其全部子进程。所以,咱们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

1. nohup

nohup 无疑是咱们首先想到的办法。顾名思义,nohup 的用途就是让提交的命令忽略 hangup 信号。让咱们先来看一下 nohup 的帮助信息:

NOHUP(1)                        User Commands                        NOHUP(1)

NAME
       nohup - run a command immune to hangups, with output to a non-tty

SYNOPSIS
       nohup COMMAND [ARG]...
       nohup OPTION

DESCRIPTION
       Run COMMAND, ignoring hangup signals.

       --help display this help and exit

       --version
              output version information and exit

可见,nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 便可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。通常咱们可在结尾加上"&"来将命令同时放入后台运行,也可用">filename 2>&1"来更改缺省的重定向文件名。

nohup 示例

[root@pvcent107 ~]# nohup ping www.ibm.com &
[1] 3059
nohup: appending output to `nohup.out'
[root@pvcent107 ~]# ps -ef |grep 3059
root      3059 984 0 21:06 pts/3    00:00:00 ping www.ibm.com
root      3067   984  0 21:06 pts/3    00:00:00 grep 3059
[root@pvcent107 ~]#

2。setsid

nohup 无疑能经过忽略 HUP 信号来使咱们的进程避免中途被中断,但若是咱们换个角度思考,若是咱们的进程不属于接受 HUP 信号的终端的子进程,那么天然也就不会受到 HUP 信号的影响了。setsid 就能帮助咱们作到这一点。让咱们先来看一下 setsid 的帮助信息:

SETSID(8)                 Linux Programmer’s Manual                 SETSID(8)

NAME
       setsid - run a program in a new session

SYNOPSIS
       setsid program [ arg ... ]

DESCRIPTION
       setsid runs a program in a new session.

可见 setsid 的使用也是很是方便的,也只需在要处理的命令前加上 setsid 便可。

setsid 示例

[root@pvcent107 ~]# setsid ping www.ibm.com
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     31094 1 0 07:28 ?        00:00:00 ping www.ibm.com
root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#

值得注意的是,上例中咱们的进程 ID(PID)为31094,而它的父 ID(PPID)为1(即为 init 进程 ID),并非当前终端的进程 ID。请将此例与nohup 例中的父 ID 作比较。

3。&

这里还有一个关于 subshell 的小技巧。咱们知道,将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出不少有趣的功能,咱们如今要讨论的就是其中之一。

当咱们将"&"也放入“()”内以后,咱们就会发现所提交的做业并不在做业列表中,也就是说,是没法经过jobs来查看的。让咱们来看看为何这样就能躲过 HUP 信号的影响吧。

subshell 示例

[root@pvcent107 ~]# (ping www.ibm.com &)
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     16270 1 0 14:13 pts/4    00:00:00 ping www.ibm.com
root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#

从上例中能够看出,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并非当前终端的进程 ID。所以并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。

回页首

disown

场景:

咱们已经知道,若是事先在命令前加上 nohup 或者 setsid 就能够避免 HUP 信号的影响。可是若是咱们未加任何处理就已经提交了命令,该如何补救才能让它避免 HUP 信号的影响呢?

解决方法:

这时想加 nohup 或者 setsid 已经为时已晚,只能经过做业调度和 disown 来解决这个问题了。让咱们来看一下 disown 的帮助信息:

disown [-ar] [-h] [jobspec ...]
	Without options, each jobspec is  removed  from  the  table  of
	active  jobs.   If  the -h option is given, each jobspec is not
	removed from the table, but is marked so  that  SIGHUP  is  not
	sent  to the job if the shell receives a SIGHUP.  If no jobspec
	is present, and neither the -a nor the -r option  is  supplied,
	the  current  job  is  used.  If no jobspec is supplied, the -a
	option means to remove or mark all jobs; the -r option  without
	a  jobspec  argument  restricts operation to running jobs.  The
	return value is 0 unless a jobspec does  not  specify  a  valid
	job.

能够看出,咱们能够用以下方式来达成咱们的目的。

灵活运用 CTRL-z

在咱们的平常工做中,咱们能够用 CTRL-z 来将当前进程挂起到后台暂停运行,执行一些别的操做,而后再用 fg 来将挂起的进程从新放回前台(也可用 bg 来将挂起的进程放在后台)继续运行。这样咱们就能够在一个终端内灵活切换运行多个任务,这一点在调试代码时尤其有用。由于将代码编辑器挂起到后台再从新放回时,光标定位仍然停留在上次挂起时的位置,避免了从新定位的麻烦。

  • 用disown -h jobspec来使某个做业忽略HUP信号。
  • 用disown -ah 来使全部的做业都忽略HUP信号。
  • 用disown -rh 来使正在运行的做业忽略HUP信号。

须要注意的是,当使用过 disown 以后,会将把目标做业从做业列表中移除,咱们将不能再使用jobs来查看它,可是依然可以用ps -ef查找到它。

可是还有一个问题,这种方法的操做对象是做业,若是咱们在运行命令时在结尾加了"&"来使它成为一个做业并在后台运行,那么就万事大吉了,咱们能够经过jobs命令来获得全部做业的列表。可是若是并无把当前命令做为做业来运行,如何才能获得它的做业号呢?答案就是用 CTRL-z(按住Ctrl键的同时按住z键)了!

CTRL-z 的用途就是将当前进程挂起(Suspend),而后咱们就能够用jobs命令来查询它的做业号,再用bg jobspec来将它放入后台并继续运行。须要注意的是,若是挂起会影响当前进程的运行结果,请慎用此方法。

disown 示例1(若是提交命令时已经用“&”将命令放入后台运行,则能够直接使用“disown”)

[root@pvcent107 build]# cp -r testLargeFile largeFile &
[1] 4825
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile
root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testLargeFile largeFile
root      4853   968  0 09:46 pts/4    00:00:00 grep largeFile
[root@pvcent107 build]# logout

disown 示例2(若是提交命令时未使用“&”将命令放入后台运行,可以使用 CTRL-z 和“bg”将其放入后台,再使用“disown”)

[root@pvcent107 build]# cp -r testLargeFile largeFile2

[1]+  Stopped                 cp -i -r testLargeFile largeFile2
[root@pvcent107 build]# bg %1
[1]+ cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile2
root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testLargeFile largeFile2
root      5824  5577  0 10:05 pts/3    00:00:00 grep largeFile2
[root@pvcent107 build]#

回页首

screen

场景:

咱们已经知道了如何让进程免受 HUP 信号的影响,可是若是有大量这种命令须要在稳定的后台里运行,如何避免对每条命令都作这样的操做呢?

解决方法:

此时最方便的方法就是 screen 了。简单的说,screen 提供了 ANSI/VT100 的终端模拟器,使它可以在一个真实终端下运行多个全屏的伪终端。screen 的参数不少,具备很强大的功能,咱们在此仅介绍其经常使用功能以及简要分析一下为何使用 screen 可以避免 HUP 信号的影响。咱们先看一下 screen 的帮助信息:

SCREEN(1)                                                           SCREEN(1)

NAME
       screen - screen manager with VT100/ANSI terminal emulation

SYNOPSIS
       screen [ -options ] [ cmd [ args ] ]
       screen -r [[pid.]tty[.host]]
       screen -r sessionowner/[[pid.]tty[.host]]

DESCRIPTION
       Screen  is  a  full-screen  window manager that multiplexes a physical
       terminal between several  processes  (typically  interactive  shells).
       Each  virtual  terminal provides the functions of a DEC VT100 terminal
       and, in addition, several control functions from the  ISO  6429  (ECMA
       48,  ANSI  X3.64)  and ISO 2022 standards (e.g. insert/delete line and
       support for multiple character sets).  There is a  scrollback  history
       buffer  for  each virtual terminal and a copy-and-paste mechanism that
       allows moving text regions between windows.

使用 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 下面的子进程了。

总结

如今几种方法已经介绍完毕,咱们能够根据不一样的场景来选择不一样的方案。nohup/setsid 无疑是临时须要时最方便的方法,disown 能帮助咱们来过后补救当前已经在运行了的做业,而 screen 则是在大批量操做时不二的选择了。

相关文章
相关标签/搜索