控制脚本

内容

  • 处理信号
  • 以后台模式运行脚本
  • 禁止挂起
  • 作业控制
  • 修改脚本优先级
  • 脚本执行自动化

除了在命令行界面世界运行脚本,还存在一些方法:向脚本发送信号、修改脚本的优先级以及在脚本运行时切换到运行模式

下面逐一讲述。

处理信号

Linux利用信号与运行在系统中的进程进行通信。我们可以通过对脚本编程,使其在收到特定信号时执行某些命令,从而实现对脚本运行的控制。

Linux信号

Linux和应用程序可以生成超过30个信号。下面列出最常见的系统信号。

信号 描述
1 SIGHUP 挂起进程
2 SIGINT 终止进程
3 SIGQUIT 停止进程
9 SIGKILL 无条件终止进程
15 SIGTERM 尽可能终止进程
17 SIGSTOP 无条件停止进程,但不是终止进程
18 SIGTSTP 停止或暂停进程,但不是终止进程
19 SIGCONT 继续运行停止的进程

默认情况下,bash shell会忽略收到的任何SIGQUITSIGTERM信号(所以交互式shell不会被终止)。但是bash shell会处理收到的SIGHUPSIGINT信号。

Shell会将这些信号传给shell脚本程序来处理。而shell脚本默认是忽略这些信号的,为了避免它,我们可以在脚本中加入识别信号的代码,并执行命令来处理信号。

生成信号

键盘上的组合可以生成两种基本的Linux信号。它在停止或暂停失控程序时非常有用。

  1. 中断程序: 使用Ctrl+C,它会发送SIGINT信号。

    (测试没起作用,尴尬了~)

  2. 暂停进程:使用Ctrl+Z,它会发送SIGTSTP信号。

    1
    2
    3
    wsx@wsx-ubuntu:~$ sleep 1000
    ^Z
    [2]+ 已停止 sleep 1000

注意:停止进程会让程序继续保留在内存中,并能从上次停止的位置继续运行。

方括号中的数字是shell自动为程序分配的作业号。shell将shell中运行的每个进程成为作业,并为其分配唯一的作业号。

退出shell时发现有停止的进程,用ps命令查看

1
2
3
4
5
6
7
8
9
wsx@wsx-ubuntu:~$ exit
exit
有停止的任务。
wsx@wsx-ubuntu:~$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 5438 5433 0 80 0 - 6153 wait pts/4 00:00:00 bash
0 T 1000 5452 5438 0 80 0 - 2258 signal pts/4 00:00:00 sleep
0 T 1000 5456 5438 0 80 0 - 2258 signal pts/4 00:00:00 sleep
4 R 1000 5525 5438 0 80 0 - 7665 - pts/4 00:00:00 ps

在表示进程状态的S列中,ps命令将已经停止作业的状态显示为T。这说明命令要么被跟踪,要么被停止了。

如果你仍想退出shell,只需要再输入一遍exit。也可以用kill生成SIGKILL信号标识上PID杀死进程。

1
2
3
4
5
wsx@wsx-ubuntu:~$ kill 5456
wsx@wsx-ubuntu:~$ kill -9 5456
wsx@wsx-ubuntu:~$ kill -9 5452
[1]- 已杀死 sleep 1000
[2]+ 已杀死 sleep 1000

捕获信号

trap命令允许我们来指定shell脚本要监看并从shell中拦截的Linux信号。

格式为:

1
trap commands signals

下面展示一个简单的例子,看如何使用trap命令忽略SIGINT信号,并控制脚本的行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
wangsx@SC-201708020022:~/tmp$ cat test1.sh
#!/bin/bash
# Testing signal trapping
#
trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT
#
echo This is a test script
#
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
#
echo "This is the end of the test script"
#

来运行测试一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
wangsx@SC-201708020022:~/tmp$ ./test1.sh
This is a test script
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
Loop #6
^C Sorry! I have trapped Ctrl-C
Loop #7
Loop #8
Loop #9
Loop #10
This is the end of the test script

捕获信号

我们也可以在shell脚本退出时进行捕获。这是在shell完成任务时执行命令的一种简便方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
wangsx@SC-201708020022:~/tmp$ cat test2.sh
#!/bin/bash
# Trapping the script exit
#
trap "echo Goodbye..." EXIT
#
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
#

wangsx@SC-201708020022:~/tmp$ ./test2.sh
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
Goodbye...

当该脚本运行到退出位置,捕获就触发了,shell会执行在trap命令行指定的命令。就算提取退出,也能够成功捕获。

修改或移除捕获

想在不同的位置进行不同的捕获处理,只需要重新使用带新选项的trap命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
wangsx@SC-201708020022:~/tmp$ cat test3.sh
#!/bin/bash
# Modifying a set trap
#
trap "echo ' Sorry... Ctrc-C is trapped.'" SIGINT # SIGINT是退出信号
#
count=1
while [ $count -le 5 ] # 当count<5的时候
do
echo "Loop #$count"
sleep 1 # 睡1秒
count=$[ $count + 1 ]
done

#
trap "echo ' I modified the trap!'" SIGINT
#
count=1
while [ $count -le 5 ] # 当count<5的时候
do
echo "Loop #$count"
sleep 1 # 睡1秒
count=$[ $count + 1 ]
done
wangsx@SC-201708020022:~/tmp$ ./test3.sh
Loop #1
Loop #2
Loop #3
^C Sorry... Ctrc-C is trapped.
Loop #4
Loop #5
Loop #1
Loop #2
Loop #3
^C I modified the trap!
Loop #4
Loop #5

相当于两次不同的捕获。

我们也可以删除已经设置好的捕获。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
wangsx@SC-201708020022:~/tmp$ cat test3.sh
#!/bin/bash
# Modifying a set trap
#
trap "echo ' Sorry... Ctrc-C is trapped.'" SIGINT # SIGINT是退出信号 在这里设置捕获
#
count=1
while [ $count -le 5 ] # 当count<5的时候
do
echo "Loop #$count"
sleep 1 # 睡1秒
count=$[ $count + 1 ]
done

#
trap -- SIGINT # 在这里删除捕获
echo "I modified the trap!"
#
count=1
while [ $count -le 5 ] # 当count<5的时候
do
echo "Loop #$count"
sleep 1 # 睡1秒
count=$[ $count + 1 ]
done
wangsx@SC-201708020022:~/tmp$ ./test3.sh
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
I modified the trap!
Loop #1
Loop #2
Loop #3
^C

信号捕获被移除之后,脚本会按照原来的方式处理SIGINT信号。所以使用Ctrl+C键时,脚本运行会退出。当然,如果是在这个信号捕获移除前接受到SIGINT信号,那么脚本还是会捕获。(因为shell脚本运行是按步的,前面没有接收到信号捕获的移除,自然不会实现信号捕获的移除)

以后台模式运行脚本

后台运行脚本

以后台模式运行shell脚本非常简单,只要再命令后加&符就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
wangsx@SC-201708020022:~$ cat test4.sh
#!/bin/bash
# Testing running in the background
#
count=1
while [ $count -le 10 ]
do
sleep 1
count=$[ $count + 1 ]
done
wangsx@SC-201708020022:~$ ./test4.sh &
[1] 69

当添加&符号后,命令和bash shell会分离而作为一个独立的后台进行运行。并返回作业号(方括号内)和进程ID(PID),Linux系统上运行的每一个进程都必须有一个唯一的PID。

当后台进程结束后,它会在终端显示出消息:

1
[1]   已完成               ./test4.sh

需要注意的是,当后台程序运行时,它仍然会使用终端显示器显示STDOUTSTDERR消息。最好是将STDOUTSTDERR进行重定向。

运行多个后台作业

我们可以在命令提示符中同时启动多个后台作用,然后用ps命令查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wangsx@SC-201708020022:~$ ./test4.sh &
[1] 117
wangsx@SC-201708020022:~$ ./test5.sh &
[2] 122
wangsx@SC-201708020022:~$ ./test6.sh &
[3] 128
wangsx@SC-201708020022:~$ ps
PID TTY TIME CMD
2 tty1 00:00:00 bash
117 tty1 00:00:00 test4.sh
122 tty1 00:00:00 test5.sh
128 tty1 00:00:00 test6.sh
135 tty1 00:00:00 sleep
136 tty1 00:00:00 sleep
137 tty1 00:00:00 ps
138 tty1 00:00:00 sleep

我们特别需要注意,如果终端退出,后台程序也会随之退出。

在非控制台下运行脚本

如果我们不想出现终端退出后台程序退出的情况,可以使用nohup命令来实现。

nohup命令运行了另外一个命令来阻断所有发送给该进程的SIGHUP信号。这会在退出终端会话时阻止进程退出。

其格式如下:

1
2
3
wangsx@SC-201708020022:~$ nohup ./test4.sh  &
[1] 156
wangsx@SC-201708020022:~$ nohup: 忽略输入并把输出追加到'nohup.out'

由于nohup命令会解除终端与进程的关联,进程也就不再同STDOUTSTDERR联系在一起。它会自动将这两者重定向到名为nohup.out的文件中。

作业控制

启动、停止终止以及恢复作业统称为作业控制。我们可以通过这几种方式完全控制shell环境中所有的进程的运行方式。

查看作业

作业控制的关键命令jobs命令。它允许查看shell当前正在处理的作业。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
wangsx@SC-201708020022:~$ cat test10.sh
#!/bin/bash
# Test job control
#
echo "Script Process ID: $$"
#
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 10
count=$[ $count + 1 ]
done
#
echo "End of script..."
#
wangsx@SC-201708020022:~$ ./test10.sh
Script Process ID: 27
Loop #1
Loop #2
^Z^C # 我的ctrl+z好像不起作用

脚本用$$变量来显示系统分配给脚本的PID。使用Ctrl+Z组合键来停止脚本(我的在这不起作用~之前好像也是)。

我们使用同样的脚本,利用&将另外一个作业作为后台进程启动。我们通过jobs -l命令查看作业的PID。

1
2
3
4
wangsx@SC-201708020022:~/tmp$ ./test10.sh > test10.out &
[1] 121
wangsx@SC-201708020022:~/tmp$ jobs -l
[1]+ 121 运行中 ./test10.sh > test10.out &

下面看jobs命令的一些参数:

参数 语法
-l 列出进程的PID以及作业号
-n 只列出上次shell发出的通知后改变了状态的作业
-p 只列出作业的PID
-r 只列出运行中的作业
-s 只列出已停止的作业

如果仔细注意的话,我们发现作业号后面有+号。带加号的作业会被当成默认作业。当前的默认作业完成处理后,带减号的作业成为下一个默认作业。任何时候只有一个带加号的作业和一个带减号的作业。

1
2
3
4
wangsx@SC-201708020022:~/tmp$ jobs -l
[1] 132 运行中 ./test10.sh > test10.out &
[2]- 134 运行中 ./test10.sh > test10.out &
[3]+ 136 运行中 ./test10.sh > test10.out &

可以发现最好运行的脚本输出排在最前面。

我们调用了kill命令向默认进程发送了一个SIGHUP信号,终止了该作业。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
wangsx@SC-201708020022:~/tmp$ ./test10.sh > test10.out &
[1] 165
wangsx@SC-201708020022:~/tmp$ ./test10.sh > test10.out &
[2] 167
wangsx@SC-201708020022:~/tmp$ ./test10.sh > test10.out &
[3] 169
wangsx@SC-201708020022:~/tmp$ jobs -l
[1] 165 运行中 ./test10.sh > test10.out &
[2]- 167 运行中 ./test10.sh > test10.out &
[3]+ 169 运行中 ./test10.sh > test10.out &
wangsx@SC-201708020022:~/tmp$ kill 169
wangsx@SC-201708020022:~/tmp$ jobs -l
[1] 165 运行中 ./test10.sh > test10.out &
[2]- 167 运行中 ./test10.sh > test10.out &
[3]+ 169 已终止 ./test10.sh > test10.out
wangsx@SC-201708020022:~/tmp$ jobs -l
[1]- 165 运行中 ./test10.sh > test10.out &
[2]+ 167 运行中 ./test10.sh > test10.out &

重启停止的作业

我们可以将已经停止的作业作为后台进程或者前台进程重启。前台进程会接管当前工作的终端,所以使用时需要注意。

要以后台模式重启一个作业,可以用bg命令加上作业号(我的Window10子系统好像确实不能使用Ctrl+Z的功能,有兴趣可以自己测试一下)。

1
2
3
4
5
6
7
8
wangsx@SC-201708020022:~/tmp$ ./test10.sh
Script Process ID: 13
Loop #1
^ZLoop #2
^C
wangsx@SC-201708020022:~/tmp$ bg
bash: bg: 当前: 无此任务
wangsx@SC-201708020022:~/tmp$ jobs

如果是默认作业,只需要使用bg命令。如果有多个作业,你得在bg命令后加上作业号。

调整谦让度

在Linux中,内核负责将CPU时间分配给系统上运行的每一个进程。调度优先级是内核分配给进程的CPU时间。在Linux系统中,由shell启动的所有进程的调度优先级默认都是相同的。

调度优先级是一个整数值,从-20(最高)到+19(最低)。默认bash shell以优先级0来启动所有进程。

我们可以使用nice命令来改变shell脚本的优先级。

nice命令

要让命令以更低的优先级运行,只要用nice-n命令行来指定新的优先级级别。

1
2
3
4
5
wsx@ubuntu:~/tmp$ nice -n 10 ./test10.sh > test10.out &
[5] 18953
wsx@ubuntu:~/tmp$ ps -p 18953 -o pid,ppid,ni,cmd
PID PPID NI CMD
18953 18782 10 /bin/bash ./test10.sh

如果想要提高优先级,需要使用超级用户权限。nice命令的-n选项不是必须的,只需要在破折号后面跟上优先级就行了。

1
2
3
4
5
6
wsx@ubuntu:~/tmp$ nice -10 ./test10.sh > test10.out &
[6] 18999
[5] Done nice -n 10 ./test10.sh > test10.out
wsx@ubuntu:~/tmp$ ps -p 18999 -o pid,ppid,ni,cmd
PID PPID NI CMD
18999 18782 10 /bin/bash ./test10.sh

renice命令

有时候我们想要改变系统上已经运行命令的优先级,这是renice命令可以做到的。它允许我们指定PID来改变它的优先级。

1
2
3
4
5
6
7
8
9
10
wsx@ubuntu:~/tmp$ ./test10.sh &
[3] 19086
wsx@ubuntu:~$ ps -p 19086 -o pid,ppid,ni,cmd
PID PPID NI CMD
19086 19070 0 /bin/bash ./test10.sh
wsx@ubuntu:~$ renice -n 10 -p 19086
19086 (process ID) old priority 0, new priority 10
wsx@ubuntu:~$ ps -p 19086 -o pid,ppid,ni,cmd
PID PPID NI CMD
19086 19070 10 /bin/bash ./test10.sh

定时运行脚本

Linux系统提供了多个在预定时间运行脚本的方法:at命令和cron表。

用at命令来计划执行任务

at命令允许指定Linux系统何时运行脚本。at命令会将作业提交到队列中,指定shell何时运行该作业。at的守护进程atd会以后台模式运行,检查作业队列来运行作业。

atd守护进程会检查系统上的一个特殊目录(通常位于/var/spool/at)来获取用at命令提交的作业。

at命令的格式

1
at [-f filename] time

默认,at命令会将STDIN的输入放入队列中。我们可以用-f参数来指定用于读取命令的文件名。time参数指定了Linux系统何时运行该脚本。

at命令能识别多种不同的时间格式。

  • 标准的小时和分钟格式,比如10:15
  • AM/PM指示符,比如10:15 PM
  • 特定可命令的时间,比如now, noon, midnight或teatime (4 PM)

除了指定运行时间,还可以指定运行的日期。

  • 标准日期格式,比如MMDDYY, MM/DD/YY或DD.MM.YY
  • 文本日期,比如Jul 4或Dec 25,加不加年份都可以
  • 还可以指定时间增量
    • 当前时间+25min
    • 明天10:15PM
    • 10:15+7天

针对不同的优先级,存在26种不同的作业队列。作业队列通常用小写字母a-z和大写字母A-Z来指代。

作业队列的字母排序越高,作业运行的优先级就越低(更高的nice值)。可以用-q参数指定不同的队列字母。

获取作业的输出

Linux系统会将提交作业的用户的电子邮件地址作为STDOUT和STDERR。任何发到STDOUT或STDERR的输出都会通过邮件系统发送给用户。

1
2
# 解决atd没启动的问题
wangsx@SC-201708020022:~/tmp$ sudo /etc/init.d/atd start
1
2
3
4
5
6
7
8
9
10
11
12
wangsx@SC-201708020022:~/tmp$ cat test13.sh
#!/bin/bash
# Test using at command
#
echo "This script ran at $(date +%B%d,%T)"
echo
sleep 5
echo "This is the script's end..."
#
wangsx@SC-201708020022:~/tmp$ at -f test13.sh now
warning: commands will be executed using /bin/sh
job 4 at Tue Sep 26 12:12:00 2017

at命令会显示分配给作业的作业号以及为作业安排的运行时间。at命令利用sendmail应用程序来发送邮件。如果没有安装这个工具就无法获得输出,因此在使用at命令时,最好在脚本中对STDOUT和STDERR进行重定向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wangsx@SC-201708020022:~/tmp$ cat test13b.sh
#!/bin/bash
# Test using at command
#
echo "This script ran at $(date +%B%d,%T)" > test13b.out
echo >> test13b.out
sleep 5
echo "This is the script's end..." >> test13b.out
#
wangsx@SC-201708020022:~/tmp$ at -M -f test13b.sh now
warning: commands will be executed using /bin/sh
job 7 at Tue Sep 26 12:16:00 2017
wangsx@SC-201708020022:~/tmp$ cat test13b.out
This script ran at 九月26,12:16:24

This is the script's end...

这里使用了-M选项来屏蔽作业产生的输出信息。

列出等待的作业

atq命令可以查看系统中有哪些作业再等待。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
wangsx@SC-201708020022:~/tmp$ at -M -f test13b.sh teatime
warning: commands will be executed using /bin/sh
job 11 at Wed Sep 27 16:00:00 2017
Can't open /var/run/atd.pid to signal atd. No atd running?
wangsx@SC-201708020022:~/tmp$ sudo /etc/init.d/atd start
[sudo] wangsx 的密码:
* Starting deferred execution scheduler atd [ OK ]
wangsx@SC-201708020022:~/tmp$ at -M -f test13b.sh teatime
warning: commands will be executed using /bin/sh
job 12 at Wed Sep 27 16:00:00 2017
wangsx@SC-201708020022:~/tmp$ at -M -f test13b.sh tomorrow
warning: commands will be executed using /bin/sh
job 13 at Wed Sep 27 21:44:00 2017
wangsx@SC-201708020022:~/tmp$ at -M -f test13b.sh 13:30
warning: commands will be executed using /bin/sh
job 14 at Wed Sep 27 13:30:00 2017
wangsx@SC-201708020022:~/tmp$ atq
11 Wed Sep 27 16:00:00 2017 a wangsx
12 Wed Sep 27 16:00:00 2017 a wangsx
13 Wed Sep 27 21:44:00 2017 a wangsx
14 Wed Sep 27 13:30:00 2017 a wangsx

作业列表中显示了作业号、系统运行该作业的日期和时间以及它所在的队列位置。

删除作业

使用atrm命令删除等待中的作业。

1
2
3
4
5
6
7
8
9
10
wangsx@SC-201708020022:~/tmp$ atq
11 Wed Sep 27 16:00:00 2017 a wangsx
12 Wed Sep 27 16:00:00 2017 a wangsx
13 Wed Sep 27 21:44:00 2017 a wangsx
14 Wed Sep 27 13:30:00 2017 a wangsx
wangsx@SC-201708020022:~/tmp$ atrm 11
wangsx@SC-201708020022:~/tmp$ atq
12 Wed Sep 27 16:00:00 2017 a wangsx
13 Wed Sep 27 21:44:00 2017 a wangsx
14 Wed Sep 27 13:30:00 2017 a wangsx

只能删除自己提交的作业,不能删除其他人的。

安排需要定期执行的脚本

如果是需要定期执行的脚本,我们不需要使用at不断提交作业,而是可以利用Linux系统的另一个功能。

Linux系统使用cron程序来安排要定期执行的作业。它会在后台运行并检查一个特殊的表(成为cron时间表),以获得已安排执行的作业。

cron时间表

cron时间表的格式如下:

1
min hour dayofmonth month dayofweek command

cron时间表允许我们用特定值、取值范围(比如1-5)或者通配符(星号)来指定条目。

例如,我们想在每天的10:15运行一个命令,可以使用:

1
15 10 * * * command

在其中三个字段使用了通配符,表明cron会在每个月的每天的10:15执行该命令。

要指定在每周一4:15PM运行命令,可以使用:

1
15 16 * * 1 command

可以用三字符的文本值mon,tue,wed,thu,fri,sat,sum或数值(0为周日,6为周六)来指定dayofweek的表项。

dayofmonth可以用1-31表示。

1
2
# 怎么在每个月的最后一天执行命令?
00 12 * * * if [`date +%d -d tomorrow` = 01 ]; then ; command

命令列表必须指定要运行的命令或脚本的全路径名。

1
2
# 例如
15 10 * * * /home/rich/test4.sh > test4out

注意:corn会用提交作业的用户账户运行脚本,所以我们在操作指定文件时必须有相应权限。

构建cron时间表

Linux提供了crontab命令来处理cron时间表。我们可以使用-l选项列出时间表。

1
2
wangsx@SC-201708020022:~/tmp$ crontab -l
no crontab for wangsx

要添加条目,使用-e选项。在添加条目时,crontab命令会启动一个文本编辑器,使用已有的cron时间表作为文件内容。

浏览cron目录

如果对时间精确性要求不高,用预配置的cron脚本目录会更方便。有4个基本目录:hourly, daily, monthly和weekly。

1
2
3
4
5
6
7
8
9
10
11
12
wangsx@SC-201708020022:~/tmp$ ls /etc/cron.*ly
/etc/cron.daily:
apport bsdmainutils man-db passwd upstart
apt-compat dpkg mdadm popularity-contest
aptitude logrotate mlocate update-notifier-common

/etc/cron.hourly:

/etc/cron.monthly:

/etc/cron.weekly:
fstrim man-db update-notifier-common

如果脚本需要每天运行一次,只要将脚本复制到daily目录,cron每天会执行它。

anacron程序

如果提交的作业需要运行时系统处于关机状态,cron不会运行那些错过的脚本。为了解决这个问题,anacron程序诞生了。

如果anacron知道某个作业错过了执行时间,它会尽快运行该作业。这个功能常用于进行常规日志维护的脚本。

anacron程序只会处理位于cron目录下的程序,比如/etc/cron.monthly。它使用时间戳来决定作业是否在正确的计划间隔内运行了,每个cron目录都有个时间戳文件,该文件位于/var/spool/anacron

anacron程序使用自己的时间表来检查作业目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
wsx@ubuntu:~$ sudo cat /var/spool/anacron/cron.monthly
[sudo] password for wsx:
20170926
wsx@ubuntu:~$ sudo cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

# These replace cron's entries
1 5 cron.daily run-parts --report /etc/cron.daily
7 10 cron.weekly run-parts --report /etc/cron.weekly
@monthly 15 cron.monthly run-parts --report /etc/cron.monthly

anacron的时间表的基本格式和cron时间表略有不同:

1
period delay identifier command

period定义了作业多久运行一次,以天为单位。anacron用此条目来检查作业的时间戳文件。delay条目会指定系统启动后anacron程序需要等待多少分钟再开始运行错过的脚本。command条目包含了run-parts程序和一个cron脚本目录名。run-parts程序负责运行目录中传给它的任何脚本。

注意了,anacron不会处理执行时间需求小于一天的脚本,所以它是不会运行/etc/cron.hourly的脚本。

identifier条目是一种特别的非空字符串,如cron-weekly。它用于唯一标识日志消息和错误邮件中的作业。

文章目录
  1. 1. 处理信号
    1. 1.1. Linux信号
    2. 1.2. 生成信号
    3. 1.3. 捕获信号
    4. 1.4. 捕获信号
    5. 1.5. 修改或移除捕获
  2. 2. 以后台模式运行脚本
    1. 2.1. 后台运行脚本
    2. 2.2. 运行多个后台作业
  3. 3. 在非控制台下运行脚本
  4. 4. 作业控制
    1. 4.1. 查看作业
    2. 4.2. 重启停止的作业
  5. 5. 调整谦让度
    1. 5.1. nice命令
    2. 5.2. renice命令
  6. 6. 定时运行脚本
    1. 6.1. 用at命令来计划执行任务
      1. 6.1.1. at命令的格式
      2. 6.1.2. 获取作业的输出
      3. 6.1.3. 列出等待的作业
      4. 6.1.4. 删除作业
    2. 6.2. 安排需要定期执行的脚本
      1. 6.2.1. cron时间表
      2. 6.2.2. 构建cron时间表
      3. 6.2.3. 浏览cron目录
      4. 6.2.4. anacron程序
|