python能用于unix吗_用Python实现低配的Unix Cron,一个能让程序在计划的时间运行的系统...

项目概述

这个项目来自 USYD INFO1112 assignment 1。目标是开发一个能让程序在计划的时间运行的系统。类似于Unix里cron。

项目结构

这个项目有三个文件构成,runner.conf, runner.py, runstatus.py。runner.conf指定了在什么时间运行什么程序,runner.py会读取这个文件并在特定时间执行特定文件,runstatus.py可以获取程序的执行状态。

例如: 在runner.conf 里的 every Tuesday at 1100 run /bin/date意味着在每周二的上午11点执行/bin/date这个程序

runner.conf格式

程序支持三种格式命令在每周的特定时间执行every day[,day...] at HHMM[,HHMM...] run ..

例如:

every Tuesday at 1100 run /bin/date意味着在每周二的上午11点执行/bin/date这个程序

特殊情况:

如果今天是周一,上面这个例子将在这周二开始运行 如果今天是周三,上面这个例子将在下个周二开始运行在某天执行 on day[,day...] at HHMM[,HHMM...] run ..

例如: on Monday,Sunday at 1300 run /bin/echo hello world意味着在这周一和周天的下午一点运行/bin/echo hello world

特殊情况: 如果现在是周一的9点,上面这个例子将在下午一点以及周天的下午一点运行 如果现在是周二,上面这个例子将在周天的下午一点以及下周一的下午一点在当天执行 at HHMM[,HHMM...] run ..

例如:

at 0800 run /bin/cp /tmp/a /tmp/b意味着在今天早上八点运行/bin/cp /tmp/a /tmp/b

特殊情况:

如果现在是9点,上面这个例子将在明早八点运行

一些错误的格式: repeated day: every Tuesday,Thursday,Thursday at 1200,1100 run /bin/date

incorrect weekday: every Tues at 1100 run /bin/date

incorrect weekday: every tuesday at 1100 run /bin/date

incorrect time: every Tuesday at 11000 run /bin/date

incorrect time: on Tuesday at 2400 run /bin/date

incorrect time: on Tuesday at 1260 run /bin/date

incorrect time: on Tuesday at 12-0 run /bin/date

duplicate run time: on Monday at 1100,1200 run /bin/echo Hello on Monday at 1000,1100 run /bin/echo there

duplicate run time: at 0600,0600 run /bin/echo hello

no program to run: on Tuesday at 1100 run

invalid program to run: on Tuesday at 1100 run /what/huh?

invalid syntax on every Friday at 1100 run /bin/echo hello

runner.py

runner.py会在后台运行。开始运行时,会把process ID写进HOME/.runner.pid​中并检查HOME/.runner.status是否存在。接着读取runner.conf,并把任务加到列表当中

runstatus.py

向runner.py发送信号,将程序的执行状态以标准输出的形式打印出来 三种状态: - 执行过了: ran ​​date-time program-path parameters执行错误: error ​date-time program-path parameters

将要执行: will run at​​date-time program-path parameters

用法

python3 runner.py & python3 runstatus.py

实现的细节

runner.py

主方法的伪代码实现:

解析runner.conf,生成task,加到tasks里。tasks是个按时间排序的队列

while tasks 不为空:

p = 取出tasks第一个task

时间差 = p.time_diff - 当前运行时间

sleep(时间差)

运行时间 += 时间差

运行程序

如果p.is_repeat:

生成新的task加入到tasks

基于面对对象思想,把每个要执行的任务当作一个对象,一起储存在一个任务列表里。

class Task:

def __init__(self, program, time_diff, is_repeat, status, record):

"""Parameter:program: the program going to runtime_diff: time difference from nowis_repeat: true if the commands contains the keyword 'every'status: can be 'will run at ', 'ran ', 'error 'record: the running time"""

self.program = program

self.time_diff = time_diff

self.is_repeat = is_repeat

self.status = status

self.record = record

由于exec会把当前程序替换掉,所以当我们想执行程序时,需要新建一个子进程,这里运用了fork和exec。

fork会创造一个子进程。主进程返回值是子进程的pid,子进程pid是0。如果pid是0,就执行,如果是-1说明fork出现错误了,其他的话,主进程应该等子进程结束。

由于父进程和子进程不共享内存,子进程发生的任何改变都不会对父进程有任何影响。但我们想知道子进程运行的结果有没有成功,这就要用到os.wait()。os.wait()返回一个tuple,如果tuple的第二个为0的话,子进程执行出现问题。

try:

pid = os.fork()

if pid == 0:

os.execv(pa,args)

raise Exception("exec error")

elif pid == -1:

raise Exception("fork error")

else:

child_status = os.wait()

if child_status[1]>>8 != 0:

raise Exception("non-executable program")

except:

# Have some errors when running the program

for t in ran_tasks:

if t == p:

t.status = "error "

if p.is_repeat == True:

delta = datetime.timedelta(seconds = p.time_diff+7*24*3600)

r = n + delta

new_prog = Task(p.program, p.time_diff + 7*24*3600, True, "will run at ",r.ctime())

tasks.append(new_prog)

tasks = sorted(tasks, key = lambda p: p.time_diff)

continue

程序在后台运行,接受到信号时,应该打印出所有程序的状态。

这涉及到两个程序间的信息交换有两种方法:共享内存。一个程序往一个文件里写,另一个程序读取这个文件。

pipe

这里用的是第一种方法,runstatus.py向runner.py发送信号,runner.py接受信号,并往.runner.status里写入东西。

def catchSignal(signum, frame):

with open(os.path.expanduser("~/.runner.status"), "w") as f:

for t1 in ran_tasks:

f.write(t1.status + t1.record + " "+ t1.program + "\n")

for t2 in tasks:

f.write(t2.status + t2.record + " "+ t2.program + "\n")

signal.signal(signal.SIGUSR1, catchSignal)

runstatus.py

向runner.py发送信号,等待runner.py写完任务状态,再把状态打印出来

try:

os.kill(pid, signal.SIGUSR1)

i = 0

try:

with open(os.path.expanduser("~/.runner.status"),"r") as f:

while(i < 5):

lines=f.readlines()

if len(lines)!= 0:

for l in lines:

print(l.strip("\n"))

file = open(os.path.expanduser("~/.runner.status"),"w")

file.close()

break

else:

time.sleep(1)

i+=1

if i==5:

print("status timeout")

sys.exit(1)

except:

print("runner.status file is missing.")

sys.exit(1)

except:

print("Failed to send the signal")

sys.exit(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python is an ideal language for solving problems, especially in Linux and Unix networks. With this pragmatic book, administrators can review various tasks that often occur in the management of these systems, and learn how Python can provide a more efficient and less painful way to handle them., Each chapter in Python for Unix and Linux System Administration presents a particular administrative issue, such as concurrency or data backup, and presents Python solutions through hands-on examples. Once you finish this book, you'll be able to develop your own set of command-line utilities with Python to tackle a wide range of problems. Discover how this language can help you:, * Read text files and extract information, * Run tasks concurrently using the threading and forking options, * Get information from one process to another using network facilities, * Create clickable GUIs to handle large and complex utilities, * Monitor large clusters of machines by interacting with SNMP programmatically, * Master the IPython Interactive Python shell to replace or augment Bash, Korn, or Z-Shell, * Integrate Cloud Computing into your infrastructure, and learn to write a Google App Engine Application, * Solve unique data backup challenges with customized scripts, * Interact with MySQL, SQLite, Oracle, Postgres, Django ORM, and SQLAlchemy, With this book, you'll learn how to package and deploy your Python applications and libraries, and write code that runs equally well on multiple Unix platforms. You'll also learn about several Python-related technologies that will make your life much easier.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值