在Linux工作环境下,我们有时可能会需要在未来某个时间执行某个命令或脚本,但是我们又不可能定个闹钟,然后到点了再去执行吧,这多麻烦。还好我们的Linux系统这么强大,提供了任务计划这个功能,我们就不需要守着点去执行相应的命令或脚本了。当我们定义好了任务计划之后,就可以去做别的事情了,等到了我们自己定义的那个时间点,你所定义的任务操作系统会自动执行,这就被称之为任务计划。下面我们来详细讲一下任务计划的相关命令及用法
一、一次性任务计划
1、at
1
2
3
4
5
6
7
8
9
10
11
12
13
|
at, batch, atq, atrm - queue, examine or delete jobs
for
later execution
# 检查或删除任务计划
SYNOPSIS
at [-V] [-q queue] [-f
file
] [-mldbv] TIME
at [-V] [-q queue] [-f
file
] [-mldbv] -t time_arg
at -c job [job...]
atq [-V] [-q queue]
atrm [-V] job [job...]
batch [-V] [-q queue] [-f
file
] [-
mv
] [TIME]
-q:指定新任务的队列名称
-l:显示待执行任务的列表,同atq命令
-d:删除指定的待执行任务,同atrm命令
|
(1)、相对时间表示法定义任务计划
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
at now | HH:MM | midnight | noon | teatime(4pm) +
#{minutes|hours|days|weeks}
[root@soysauce ~]
# date
Sun Dec 6 12:18:36 CST 2015
[root@soysauce ~]
# at now +5min # 5分钟后执行
at>
ls
/tmp
at>
cat
/etc/fstab
at> <EOT>
# 按Ctrl+d即可提交任务计划
job 3 at 2015-12-06 12:23
[root@soysauce ~]
# date
Sun Dec 6 12:20:21 CST 2015
[root@soysauce ~]
# at 4pm +3days # 三天后的下午4点执行
at>
cat
/etc/issue
at>
date
at> <EOT>
job 4 at 2015-12-09 16:00
You have new mail
in
/var/spool/mail/root
# 执行结果将以邮件形式发送
|
(2)、绝对时间表示法定义任务计划
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
at [ HH:MM | midnight | noon | teatime(4pm)] MMDDYY | MM
/DD/YY
| DD.MM.YY
[root@soysauce ~]
# date
Sun Dec 6 12:50:16 CST 2015
[root@soysauce ~]
# at 12:58 12062015 # 2015年12月6日 12:58分执行
at>
echo
"Hello World"
at>
echo
"Hello Python"
at> <EOT>
job 9 at 2015-12-06 12:58
[root@soysauce ~]
# date
Sun Dec 6 12:53:05 CST 2015
[root@soysauce ~]
# at midnight 06.12.2015 # 2015年12月6日 00:00分执行
at>
cat
/etc/inittab
at>
echo
"Hello"
at> <EOT>
job 11 at 2015-12-06 00:00
|
(3)、查看待执行任务列表
1
2
3
4
5
6
7
8
9
|
at -l 或 atq
[root@soysauce ~]
# at -l
4 2015-12-09 16:00 a root
9 2015-12-06 12:58 a root
You have new mail
in
/var/spool/mail/root
[root@soysauce ~]
# atq
4 2015-12-09 16:00 a root
9 2015-12-06 12:58 a root
|
(4)、取消指定的待执行任务
1
2
3
4
5
6
7
8
9
10
|
at -d AT_JOB_ID 或 atrm AT_JOB_ID
[root@soysauce ~]
# atq
4 2015-12-09 16:00 a root
9 2015-12-06 12:58 a root
[root@soysauce ~]
# at -d 4 # 删除4号作业
[root@soysauce ~]
# at -l
9 2015-12-06 12:58 a root
[root@soysauce ~]
# atrm 9 # 删除9号作业
[root@soysauce ~]
# atq
|
(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
37
38
39
|
[root@soysauce ~]
# at now +5min
at>
ls
/
at> <EOT>
job 13 at 2015-12-06 13:05
[root@soysauce ~]
# at -l
12 2015-12-06 13:02 a root
13 2015-12-06 13:05 a root
[root@soysauce ~]
# at -c 13
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
umask
22
HOSTNAME=soysauce;
export
HOSTNAME
SHELL=
/bin/bash
;
export
SHELL
HISTSIZE=1000;
export
HISTSIZE
SSH_CLIENT=172.16.1.100\ 49853\ 22;
export
SSH_CLIENT
SSH_TTY=
/dev/pts/0
;
export
SSH_TTY
USER=root;
export
USER
MAIL=
/var/spool/mail/root
;
export
MAIL
PATH=
/usr/local/sbin
:
/usr/local/bin
:
/sbin
:
/bin
:
/usr/sbin
:
/usr/bin
:
/root/bin
;
export
PATH
INPUTRC=
/etc/inputrc
;
export
INPUTRC
PWD=
/root
;
export
PWD
LANG=en_US.UTF-8;
export
LANG
SSH_ASKPASS=
/usr/libexec/openssh/gnome-ssh-askpass
;
export
SSH_ASKPASS
SHLVL=1;
export
SHLVL
HOME=
/root
;
export
HOME
LOGNAME=root;
export
LOGNAME
CVS_RSH=
ssh
;
export
CVS_RSH
SSH_CONNECTION=172.16.1.100\ 49853\ 172.16.1.110\ 22;
export
SSH_CONNECTION
LESSOPEN=\|
/usr/bin/lesspipe
.sh\ %s;
export
LESSOPEN
G_BROKEN_FILENAMES=1;
export
G_BROKEN_FILENAMES
OLDPWD=
/tmp/test/testbin
;
export
OLDPWD
cd
/root
|| {
echo
'Execution directory inaccessible'
>&2
exit
1
}
${SHELL:-
/bin/sh
} << `(
dd
if
=
/dev/urandom
count=200 bs=1 2>
/dev/null
|LC_ALL=C
tr
-d -c
'[:alnum:]'
)`
ls
/
# 此为我们指定的任务
|
2、batch
1
2
3
4
5
6
|
batch [-V] [-q queue] [-f
file
] [-
mv
] [TIME]
# 当系统不繁忙时执行任务计划,与at用法类似
[root@soysauce ~]
# batch now +3min
at>
echo
"Hello Python"
at> <EOT>
job 14 at 2015-12-06 13:27
|
补充:/etc/at.deny和/etc/at.allow
①如果at.allow存在,而at.deny不存在,那么在at.allow文件中定义的用户可以使用at
②如果at.allow不存在,而at.deny存在,没有定义在deny中的用户可以使用at
③如果at.allow和at.deny都不存在,那么只有root用户可以使用at
④如果at.allow和at.deny都存在,那么只有at.allow中的用户可以使用at
二、周期性任务计划
1、crontab与anacron
-
crontab:crontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond服务,crond进程每分钟会定期检查是否有要执行的任务,如果有,则自动执行该任务。依赖于crond服务
-
anacron:cron的补充,能够实现让cron因为各种原因在过去的时间该执行而未执行的任务在恢复正常执行一次。依赖于nancron服务
2、Crontab任务种类及格式定义
(1)、系统cron任务:/etc/crontab 分钟 小时 天 月 周 用户 任务
1
2
3
4
5
6
7
8
9
10
11
|
[root@soysauce ~]
# cat /etc/crontab
SHELL=
/bin/bash
# 执行任务所使用的解释器
PATH=
/sbin
:
/bin
:
/usr/sbin
:
/usr/bin
# 执行任务所使用的PATH环境变量
MAILTO=root
# 执行任务完成后的结果通过邮件发送给谁
HOME=/
# 执行任务时使用的HOME变量作为家目录
# run-parts
01 * * * * root run-parts
/etc/cron
.hourly
# 每小时任务,run-parts可以运行目录下所有脚本
02 4 * * * root run-parts
/etc/cron
.daily
# 每日任务
22 4 * * 0 root run-parts
/etc/cron
.weekly
# 每周任务
42 4 1 * * root run-parts
/etc/cron
.monthly
# 每月任务
|
(2)、用户cron任务:/var/spool/cron/USERNAME 分钟 小时 天 月 周 任务
1
2
3
4
5
6
|
[root@soysauce
cron
]
# crontab -l
# Update the system time
* * *
/1
* *
/usr/sbin/ntpdate
s2m.
time
.edu.cn &>
/dev/null
# Just echo "Hello Python"
*
/10
* * * *
/bin/echo
"Hello Python"
# 用户cron不需要指定用户
|
(3)、补充anacron:/etc/anacrontab 检查频率 分钟 任务注释信息 运行的任务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@soysauce
cron
]
# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=
/bin/sh
# 执行任务所使用的解释器
PATH=
/sbin
:
/bin
:
/usr/sbin
:
/usr/bin
# 执行任务所使用的PATH环境变量
MAILTO=root
# 执行任务完成后的结果通过邮件发送给谁
1 65
cron
.daily run-parts
/etc/cron
.daily
7 70
cron
.weekly run-parts
/etc/cron
.weekly
30 75
cron
.monthly run-parts
/etc/cron
.monthly
# 每天开机之后的第65分钟检查cron.daily是否执行,没有则执行
# 每隔7天开机之后的第70分钟检查cron.weekly是否执行,没有则执行
# 每隔30天开机之后的75分钟检查cron.monthly是否执行,没有则执行
|
3、时间的有效取值
1
2
3
4
5
6
7
8
9
|
分钟:0-59
小时:0-23
天:1-31
月:1-12
周:0-7,0和7都表示周日
|
4、时间通配表示
①*: 对应时间的所有有效取值
1
2
3
4
5
|
3 * * * *
# 每天每小时的第三分钟执行一次
3 * * * 7
# 每周日每小时的第三分钟执行一次
13 12 6 7 *
# 每年的7月6日12点13分执行一次
|
②,: 离散时间点:
1
|
10,40 02 * * 2,5
# 每周二和周五的凌晨2点10分和40分执行一次
|
③-:连续时间点:
1
|
10 02 * * 1-5
# 周一至周五的凌晨2点10分执行一次
|
④/#: 对应取值范围内每多久一次
1
2
3
4
5
6
7
8
|
*
/3
* * * *
# 每三分钟执行一次
注意:比所要求小的时间单位必须要给定时间点(每天执行 那么分钟 小时都要给定时间 不能用*)
如:
08 *
/2
* * *
# 每两小时执行一次
10 04 *
/2
* *
# 每两天执行一次
|
5、cron的环境变量
1
2
3
|
cron
默认PATH
/bin
:
/sbin
:
/usr/bin
:
/usr/sbin
# cron执行所有命令都去PATH环境变量指定的路径下去找
|
6、执行结果将以邮件形式发送
1
2
3
|
*
/3
* * * *
/bin/cat
/etc/fstab
>
/dev/null
# 错误信息仍然发送给管理员
*
/3
* * * *
/bin/cat
/etc/fstab
&>
/dev/null
# 所有信息都不发送给管理员,无论是否正确执行
|
7、用户任务计划管理
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
38
39
40
41
42
43
44
45
46
47
48
49
50
|
crontab
- maintain
crontab
files
for
individual
users
(ISC Cron V4.1)
# 管理用户的周期性任务计划
SYNOPSIS
crontab
[-u user]
file
crontab
[-u user] [-l | -r | -e] [-i] [-s]
-l: 列出当前用户的所有
cron
任务
-e: 编辑任务计划
-r: 移除所有任务
-u USERNAME: 管理其用户的
cron
任务
[root@soysauce
cron
]
# pwd
/var/spool/cron
# 所有用户的cron任务计划都会保存在此目录下与用户同名的文件当中
[root@soysauce
cron
]
# ls
root
[root@soysauce
cron
]
# cat root # 查看这个文件,此时为空
[root@soysauce
cron
]
# crontab -e # 编辑任务计划条目
crontab
: installing new
crontab
[root@soysauce
cron
]
# crontab -l # 查看任务计划列表
# Update the system time
* * *
/1
* *
/usr/sbin/ntpdate
s2m.
time
.edu.cn &>
/dev/null
# Just echo "Hello Python"
*
/10
* * * *
/bin/echo
"Hello Python"
[root@soysauce
cron
]
# cat root # 用cat命令查看是一样的
# Update the system time
* * *
/1
* *
/usr/sbin/ntpdate
s2m.
time
.edu.cn &>
/dev/null
# Just echo "Hello Python"
*
/10
* * * *
/bin/echo
"Hello Python"
[root@soysauce
cron
]
# crontab -e
crontab
: installing new
crontab
"/tmp/crontab.XXXXzJD87o"
:5: bad day-of-week
errors
in
crontab
file
, can't
install
.
Do you want to retry the same edit? y
# 如果编辑之后又语法错误,就会提示是否继续编辑
[root@soysauce
cron
]
# crontab -r # 移除所有cron任务,并且文件也会一并删除
[root@soysauce
cron
]
# ls
[root@soysauce
cron
]
# crontab -l
no
crontab
for
root
[root@soysauce
cron
]
# crontab -u hadoop -e # 为hadoop用户添加cron任务
no
crontab
for
hadoop - using an empty one
crontab
: installing new
crontab
[root@soysauce
cron
]
# crontab -u hadoop -l
# Just echo "Hello Python"
*
/10
* * * *
/bin/echo
"Hello Python"
[root@soysauce
cron
]
# su - hadoop
[hadoop@soysauce ~]$
crontab
-l
# 可以看到hadoop用户的cron任务已然生成
# Just echo "Hello Python"
*
/10
* * * *
/bin/echo
"Hello Python"
|
三、sudo详解
sudo条目(/etc/sudoers)定义格式: who which_hosts=(runas) TAG:command
谁(who)能够以哪个用户(runas)的身份通过什么主机(which host)执行什么命令(command)
1、who
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
User_List ::= User |
User
','
User_List
User ::=
'!'
* username |
'!'
*
'#'
uid |
'!'
*
'%'
group |
'!'
*
'+'
netgroup |
'!'
*
'%:'
nonunix_group |
'!'
* User_Alias
Examples:
# User alias specification
User_Alias FULLTIMERS = millert, mikef, dowdy
User_Alias PARTTIMERS = bostley, jwfox, crawl
User_Alias WEBMASTERS = will, wendy, wim
|
2、which_hosts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
Host_List ::= Host |
Host
','
Host_List
Host ::=
'!'
*
hostname
|
'!'
* ip_addr |
'!'
* network(
/netmask
)? |
'!'
*
'+'
netgroup |
'!'
* Host_Alias
# Host alias specification
Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
SGI = grolsch, dandelion, black :\
ALPHA = widget, thalamus, foobar :\
HPPA = boa, nag, python
Host_Alias CUNETS = 128.138.0.0
/255
.255.0.0
Host_Alias CSNETS = 128.138.243.0, 128.138.204.0
/24
, 128.138.242.0
Host_Alias SERVERS = master, mail, www, ns
Host_Alias CDROM = orion, perseus, hercules
|
3、runas
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Runas_List ::= Runas_Member |
Runas_Member
','
Runas_List
Runas_Member ::=
'!'
* username |
'!'
*
'#'
uid |
'!'
*
'%'
group |
'!'
* +netgroup |
'!'
* Runas_Alias
# Runas alias specification
Runas_Alias OP = root, operator
Runas_Alias DB = oracle, sybase
Runas_Alias ADMINGRP = adm, oper
|
4、command
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
|
Cmnd_List ::= Cmnd |
Cmnd
','
Cmnd_List
commandname ::= filename |
filename args |
filename
'""'
Cmnd ::=
'!'
* commandname |
'!'
* directory |
'!'
*
"sudoedit"
|
'!'
* Cmnd_Alias
# Cmnd alias specification
Cmnd_Alias DUMPS =
/usr/bin/mt
,
/usr/sbin/dump
,
/usr/sbin/rdump
,\
/usr/sbin/restore
,
/usr/sbin/rrestore
Cmnd_Alias KILL =
/usr/bin/kill
Cmnd_Alias PRINTING =
/usr/sbin/lpc
,
/usr/bin/lprm
Cmnd_Alias SHUTDOWN =
/usr/sbin/shutdown
Cmnd_Alias HALT =
/usr/sbin/halt
Cmnd_Alias REBOOT =
/usr/sbin/reboot
Cmnd_Alias SHELLS =
/usr/bin/sh
,
/usr/bin/csh
,
/usr/bin/ksh
, \
/usr/local/bin/tcsh
,
/usr/bin/rsh
, \
/usr/local/bin/zsh
Cmnd_Alias SU =
/usr/bin/su
Cmnd_Alias PAGERS =
/usr/bin/more
,
/usr/bin/pg
,
/usr/bin/less
|
5、tag
1
2
|
Tag_Spec ::= (
'NOPASSWD:'
|
'PASSWD:'
|
'NOEXEC:'
|
'EXEC:'
|
'SETENV:'
|
'NOSETENV:'
)
|
6、sudo命令
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
sudo
, sudoedit - execute a
command
as another user
SYNOPSIS
sudo
-h | -K | -k | -L | -V
sudo
-
v
[-AknS] [-p prompt]
-l:查看用户授权条目
-K:清除密码的有效期限,即下次再执行
sudo
时便需要输入密码
例:允许hadoop可以修改除了eth0之外的所有接口属性
[hadoop@CentOS5 ~]$
/sbin/ifconfig
eth0 172.16.1.115
/16
SIOCSIFADDR: Permission denied
SIOCSIFNETMASK: Permission denied
SIOCSIFBROADCAST: Permission denied
SIOCSIFFLAGS: Permission denied
[hadoop@CentOS5 ~]$
sudo
/sbin/ifconfig
eth0 172.16.1.115
/16
# hadoop用户不在sudoers列表中
[
sudo
] password
for
hadoop:
hadoop is not
in
the sudoers
file
. This incident will be reported.
[hadoop@CentOS5 ~]$
exit
[root@CentOS5 ~]
# visudo
[root@CentOS5 ~]
# tail -1 /etc/sudoers # 定义能够修改eth0之外的接口
hadoop ALL=(ALL)
/sbin/ifconfig
, !
/sbin/ifconfig
eth0 [[\:digit\:]]*
[root@CentOS5 ~]
# su - hadoop
[hadoop@CentOS5 ~]$
sudo
/sbin/ifconfig
eth0 172.16.1.115
/16
# 提示不能修改eth0
[
sudo
] password
for
hadoop:
Sorry, user hadoop is not allowed to execute
'/sbin/ifconfig eth0 172.16.1.115/16'
as root on CentOS
[hadoop@CentOS5 ~]$
sudo
/sbin/ifconfig
lo 127.0.0.1
/8
# lo接口修改成功
[
sudo
] password
for
hadoop:
[hadoop@CentOS5 ~]$
/sbin/ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:FE:82:38
inet addr:172.16.1.110 Bcast:172.16.255.255 Mask:255.255.0.0
inet6 addr: fe80::20c:29ff:fefe:8238
/64
Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:35524 errors:0 dropped:0 overruns:0 frame:0
TX packets:22083 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:37848654 (36.0 MiB) TX bytes:2718196 (2.5 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1
/128
Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:144 errors:0 dropped:0 overruns:0 frame:0
TX packets:144 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:20256 (19.7 KiB) TX bytes:20256 (19.7 KiB)
例:允许hadoop可以修改除了root用户之外的所有用户的密码
[root@CentOS5 ~]
# visudo
[root@CentOS5 ~]
# tail -1 /etc/sudoers
hadoop ALL=(ALL)
/usr/bin/passwd
[[\:alpha\:]]*, !
/usr/bin/passwd
root
[root@CentOS5 ~]
# su - hadoop
[hadoop@CentOS5 ~]$
sudo
/usr/bin/passwd
[
sudo
] password
for
hadoop:
Sorry, user hadoop is not allowed to execute
'/usr/bin/passwd'
as root on CentOS5.8.
[hadoop@CentOS5 ~]$
sudo
/usr/bin/passwd
root
[
sudo
] password
for
hadoop:
Sorry, user hadoop is not allowed to execute
'/usr/bin/passwd root'
as root on CentOS5.8.
[hadoop@CentOS5 ~]$
sudo
/usr/bin/passwd
tom
[
sudo
] password
for
hadoop:
Changing password
for
user tom.
New UNIX password:
BAD PASSWORD: it is WAY too short
Retype new UNIX password:
passwd
: all authentication tokens updated successfully.
|