简介

        本文介绍在Linux下运行程序时的命令。包括:Java部署命令,会话断开后不停止执行、后台运行程序、定时运行程序。相关命令有:nohup/setsid/disown/fg/bg/at

运行Java的命令

示例命令

nohup java -Xmx256m -Dspring.profiles.active=test -jar /home/demo-0.0.1-SNAPSHOT.jar >/home/logs/demo.log 2>&1 &

说明


  • nohup
  • 会话断开不停止此进程
  • -Dspring.profiles.active=test
  • >/home/logs/demo.log
  • 将标准输出写到文件里边
  • 2>&1
  • 将标准错误写到标准输出里边。因为前边标准输出已经与文件关联,此时,标准错误也会输出到那个文件
  • &
  • 后台执行

让程序在会话断开后仍执行

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

法1:nohup

说明

用ssh时,只能等命令运行完再关闭ssh对话,若关闭了会话,则命令会停止执行。

nohup:在退出ssh对话后仍然运行该命令。(使进程忽略hangup信号,从而持续执行。)

示例

用法:nohup xxx     //xxx表示要运行的命令

法2:setsid

说明

        setsid作用:使此进程不属于接收HUP 信号的终端的子进程,也就不会受到 HUP 信号的影响了。

        setsid中的sid指的是session id,意指以该命令运行的进程是一个新的session,因此其父进程id不属于当前终端。实际上,setsid运行的进程,其父进程id(PPID)为1(init 进程的 PID)。

示例

[root@lwy ~]# sleep 100 &
[2] 10661
[root@lwy ~]# ps -ef|grep sleep
root 10661 9835 0 16:20 pts/1 00:00:00 sleep 100
root 10663 9835 0 16:20 pts/1 00:00:00 grep sleep
[root@lwy ~]# setsid sleep 100
[root@lwy ~]# ps -ef|grep sleep
root 10661 9835 0 16:20 pts/1 00:00:00 sleep 100
root 10666 1 0 16:20 ? 00:00:00 sleep 100
root 10668 9835 0 16:20 pts/1 00:00:00 grep sleep

法3: ()与&

说明

        将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出很多功能。

        将"&"也放入“()”内之后,会发现所提交的作业并不在作业列表中,即:无法通过jobs来查看,躲过 HUP 信号的影响。

示例

[root@lwy ~]# (sleep 100 &)
[root@lwy ~]# ps -ef|grep sleep
root 10588 1 0 15:57 pts/1 00:00:00 sleep 100
root 10590 9835 0 15:57 pts/1 00:00:00 grep sleep
[root@lwy ~]# ps -p 9835 ##可以看出sleep 100 的父进程是当前shell终端
PID TTY TIME CMD
9835 pts/1 00:00:00 bash

        可以看出,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。 

法4:disown

说明

        如果我们未加任何处理就已经提交了命令,这时想加 nohup 或者 setsid 已经为时已晚,只能通过作业调度和 disown 来解决这个问题了。

我们可以用如下方式来达成我们的目的。


  • 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 来将它放入后台并继续运行。需要注意的是,如果挂起会影响当前进程的运行结果,慎用此方法。

示例

[root@lwy ~]# sleep 100 &
[1] 10895
[root@lwy ~]# jobs
[1]+ Running sleep 100 &
[root@lwy ~]# disown -h %1
[root@lwy ~]# ps -ef|grep sleep
root 10895 9835 0 17:04 pts/1 00:00:00 sleep 100
root 10898 9835 0 17:04 pts/1 00:00:00 grep sleep

此时退出终端也无妨,因为此进程已不接受任何HUP信号。 

后台运行(ctrl+z / fg / bg)

简介


  • ctrl +z

  • 含义:suspend
  • 作用:将其放到后台执行。

  • fg

  • foreground
  • 含义:将程序放到前台执行

  • bg

  • background
  • 含义:将程序放到后台执行


实例

如果前台执行一个程序很久没执行完,那么可以用 ctrl+z挂起它,系统会做类似如下提示:

[1]+  Stopped                 sleep 100

然后可以用bg把程序调到后台执行:

[root@lwy ~]# bg 1
[1]+ sleep 100 &

注:bg后加作业号。(注意:不是pid)

查看当前后台执行的进程状态:

[root@lwy ~]# jobs -l
[1]+ 10111 Running sleep 100 &

如果想调回前台,用fg+作业号:

[root@lwy ~]# fg 1
sleep 100

但是后台运行的程序还是会输出到屏幕上,会干扰工作,所以记得要重定向到一个文件中。

at(定时执行)

其他网址

​Linux之at命令_weixin_34162228的博客-​

简介

at命令是​一次性​定时计划任务,执行完一个任务后不再执行此任务了。

相关命令

    at:在特定的时间执行一次性的任务;

    atq:列出用户的计划任务,若是超级用户将列出所有用户的任务,输出格式为:作业号、日期、小时、队列和用户名;

    atrm:根据job number删除at任务;

    batch:在系统负荷允许的情况下执行at任务,就是在系统空闲的情况下才执行at任务。

案例1:三天后的下午5点执行/bin/ls /

命令:

[root@vms002 /]# at 5pm+3 days

at> /bin/ls /<EOT>

job 1 at Fri Jun 14 17:00:00 2019

案例2:一分钟后执行/tmp/date文件中的内容

命令:

[root@vms002 /]# cat /tmp/date        #查看/tmp/date文件中内容

#!/bin/bash

date "+%F %T" > /root/date.log

[root@vms002 /]# at -f /tmp/date now +1 minutes   #设置1分钟后执行/tmp/date文件中的内容

job 4 at Tue Jun 11 15:47:00 2019

at命令格式

at [选项] [时间]

Ctrl + D  结束at命令的输入

在使用at命令的时候,一定要保证atd进程的启动。

[root@vms002 /]# ps -ef|grep -v grep|grep atd

rpcuser    1550      1  0 6月10 ?       00:00:00 /usr/sbin/rpc.statd --no-notify

root       1552      1  0 6月10 ?       00:00:00 /usr/sbin/atd -f

选项


选项



含义



-m



当指定的任务被完成后,将给用户发送邮件,即使没有标准输出



-I



atq的别名



-d



atrm的别名



-v



显示任务将被执行的时间



-c



打印任务的内容到标准输出



-V



显示版本信息



-q <队列>



使用指定的队列



-f <文件>



从指定文件读入任务而不是从标准输入读入



-t <时间参数>



以时间参数的形式提交要运行的任务


指定时间的方法


  • hh:mm(小时:分钟)式的时间指定。假如该时间已过去,那么就放在第二天执行。 例如:04:00
  • 12小时计时制。即在时间后面加上AM(上午)或PM(下午)来说明是上午还是下午。 例如:12pm
  • 具体日期。指定格式为month day(月 日)或mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年),指定的日期必须跟在指定时间的后面。 例如:04:00 2009-03-1
  • 相对计时法。指定格式为:now + count time-units ,now就是当前时间,time-units是时间单位,这里能够是minutes(分钟)、hours(小时)、days(天)、weeks(星期)。count是时间的数量,几天,几小时。 例如:now + 5 minutes + 3 days
  • 模糊时间段。midnight(深夜),noon(中午),teatime(饮茶时间,一般是下午4点)等模糊的词语来指定时间。
  • today(今天)、tomorrow(明天)来指定完成命令的时间。例如:at 17:00 tomorrow

相关配置文件


时间规范的确切定义可以在/usr/share/doc/at-3.1.13/timespec中查看;默认情况下计划任务都是存放在/var/spool/at/文件夹中;root用户可以在任何情况下使用at命令,而其他用户使用at命令的权限定义在/etc/at.allow(被允许使用计划任务的用户)和/etc/at.deny(被拒绝使用计划任务的用户)文件中,默认没有文件需要自己创建允许用户和拒绝用户文件;如果/etc/at.allow文件存在,只有在该文件中的用户名对应的用户才能使用at;如果/etc/at.allow文件不存在,/etc/at.deny存在,所有不在/etc/at.deny文件中的用户可以使用at;at.allow比at.deny优先级高,执行用户是否可以执行at命令,先看at.allow文件中有没有才看at.deny文件;如果/etc/at.allow和/etc/at.deny文件都不存在,则只有root用户能使用at;一个空内容的/etc/at.deny表示任何用户都能使用at命令,这是默认的配置;一般情况下这两个文件存在一个即可。如果只有少数几个用户需要使用计划任务,那么就保留at.allow文件,如果大部分用户都要使用计划任务,那么保留at.deny即可。