,
>>cd .ssh
>>ll //检查是否将id_leop_lap.pub成功拷贝
>>cat id_leop_lap.pub > authoriezed_leys
>>exit
再次使用命令, ssh user@登录到远端机, 这是无须身份验证即可登录。
步骤2,
在本地己上创建一个NFS目录, 这里包含将要在远端机上运行的python代码, 之后建立symbol一个连接。
步骤3,建立python代码。
....
machines=[“1.2.3.4”,“11.22.33.44”,“33.22.112.11”,“33.11.33.22”]
cmd='uname'
for machine in machines:
subprocess.call("ssh user@% %s" % (machine, cmd), shell=True)
....
在实际工作中为了集中管理一些信息, 比如ip地址和主机名称, 以及用运行的命令, 我们经常要用到ini文件, python提供的库
Configarser可以非常方便地将这些信息从文件中提取并保存在数组中, ini文件的格式如下...
=========config.ini==============
[section_name]
items_1: value1
items_2: value2
items_3: values3
...
[section_name]
items_1: value1
...
items_n: valuen
...
========fetch info from config.ini========
....
import ConfigParser
hewei = []
xiaolei = []
jiaxuan = []
Config = ConfigParser.ConfigParser()
Config.read("./test.ini")
heweiinfo = Config.items("hewei")
xiaoleiinfo=Config.items("xiaolei")
jiaxuaninfo = Config.items("jiaxuan")
for i in heweiinfo:
hewei.append(i[1])
print i
for i in xiaoleiinfo:
xiaolei.append(i[1])
print i
for i in jiaxuaninfo:
jiaxuan.append(i[1])
print i
....
为了管理对文件的改动, 可以应用库pryinotify, 它可以帮助系统管理员监视文件的改动, 即通过回调函数可以通知文件系统是否被改动。
七。包管理
distutils是创建可安装的python包的主要工具, 现在setuptools在distutils基础上有了加强。“Egg”是指最终形成的python安装包或者库, 如同rmp或者deb文件。
distutils基本的使用步骤是,
1。编写setup脚本, setup.py文件
2。将要发布的py文件放在同一路径下
3。创建发布
可以使用easy_install来对egg进行下载, 安装和创建。 easy_install是python库与setuptools的组合。
下面是一些easy_install所具有的一些特点,首先他可以搜索位于网页上的包(egg);从URL安装源程序;安装位于本地或者网络文件系统上的egg;更新包;
下面简介一下如何创建egg,
1。安装setuptools
2。创建想要加入egg的文件
3。创建setup.py文件
4。运行
一些其他的安装发布工具如,epm, buildout等,
八。进程和并行
1. 进程管理
作为系统管理员您可能对一下的概念要熟悉,启动脚本,run level, daemons, cron任务,long-running进程(比如 网络应用),并行等。
python提供的库subprocess可以创建新的进程, 并提供于标准书输入/出/错误输出对话的功能。
python2。4所提供的库 subprocess可以取代一些老的方法, 比如, os.system, os.spwan, os.popen 和popen2。
简单例子如下,
...
import subprocess
subprocess.call('df -k', shell=True)
...
如果对派生的进程输出并不关心(将标准输出屏蔽), 可以将标准输出冲定向, 如下,
ret = subprocess.call("ping -c 192.168.1.2",
shell=True,
stdout=open("/dev/null", 'w'),
stderr=subprocess.STDOUT)
...
subprocess.call是属于同步进程调用(即等待回答),subprocess.popen属于异步进程调用(主进程不会处于等待的状态)。
long-running进程的管理可以使用screen, 一个主要特点是screen可以让系统管理员与被管理对象挂钩或者解钩。
2。python中的线程
以下的几个应用实例可能是系统管理员的面对的问题,
1。)服务起的压力测试
2。)自动网络查找
3。)同时获取多个网页
4。)执行与网络有关的工作
通常的情况下使用线程的同时要使用队列(queue), 原因如下。 1。)单单使用线程会增加对程序分析和操作的难度;
2。)使用queue的同时也使用了mutex对数据进行保护。
下面的实例简单地表明了thread和queue的关系, 首先创建一个队列, 在这个队列中将要保存要完成的任务及其所需要的参数,比如在这个例子中我们需要打印出定义好的字符串(strs);之后创建一定数量的thread(num_threads), 在thread中任务将被执行,
同时还要将thread与上一步创建的队列相关联, 以便使thread可以从队列中提取相应的参数, thread同时也被队列所管理。
-》1。#!/usr/bin/env python
-》2。from threading import Thread
-》3。from Queue import Queue
-》4。num_threads = 3
-》5。queue = Queue()
#任务参数
-》6。strs = ["first --", "second --", "third --", "fourth --", "Fifth--", "Sixth--"]
-》7。def dosomething(i, q):
-》8。 while True:
#试图提取参数,交给空闲的thread去完成任务
-》9。 val = q.get()
-》10 print " this thread %s saying : %s" %(i, val)
#任务完成, 通知队列(当前thread为空闲,可以完成下一个任务)
-》11 q.task_done()
-》12 #end while
-》13 #end def
-》14 print "---------Program Entry-----------"
#创建thread,告之要完成的任务,并将它(们)与队列相关联, 启动thread
-》15 for i in range(num_threads):
-》16 worker = Thread(target=dosomething, args=(i, queue))
-》17 worker.setDaemon(True)
-》18 worker.start()
-》19 #end for
#将thread要执行的任务的参数放入队列,thread可以执行任务, 如果没有这些参数(q.get() 第9行)任务无法完成, thread将退出。
-》20 for val in strs:
-》21 queue.put(val)
-》22 end for
#这个函数非常重要, 他来管理队列的状态, 确保队列中所有项被处理, 它内部有计数器,当新的项将如时, 计数器加一, 当某一个
thread调用了queue.task_done()后, 其计数器减以, 当计数器为0时。
-》23 queue.join()
-》24 print "---------job over--------"
此外对于无论是系统管理员合适程序设计员来说, 另外一个十分有用的功能就是延时控制, python提供的类timer可以实现基本的
对时间延时的控制,
from threading import Timer
def on_time():
print " program is really over !"
#define
#延时5秒
t = Timer(5, on_time)
t.start()
在系统管理中, 有时管理员可以通过脚本自动监视默写动作, 比如监视两个目录的一致性, 在必要是可以自动执行给定的动作(也就是事件驱动的函数)。
python不但可以使您创建thread,还可以创建进程, 这就要用到库process, 起用法基本与Thread一致。
如何协管理任务的执行是系统管理员重要的工作, 通常可以将要自动执行的脚本放在/etc/cron.xxx目录下面。
例如, 在夜间监视硬盘使用情况的bash脚本,
df -h | mail -s "Night Disk Usage Report" staff@example.com
python程序有时需要以daemon的形式运行, 那么到底什么算是daemon呢? 满足daemon的条件有三, 首先, 要运行在后台, 其次, 要与
其父进程脱钩, 最后, 不能有控制终端, 如下例,
import sys, os
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
#perform first fork
try:
pid = os.fork()
if pid > 0:
sys.exit(0) #exit first parent
except OSError, e:
sys.stderr.write("fork #1 failed: (%d) %s"\n % (e.errno, e.strerror) )
sys.exit(1)
#decouple from parent environment
os.chdir("/") #使daemon安装在根路径, 因为其始终存在。 另外可以防止对路径进行umount时使daemon被umount
os.umask(0) #改变daemon的权限, 使其拥有最大的权限
os.setsid() #使这个daemon成为新的对话和进程组的头,所以它没有控制终端。
#perform second fork
try:
pid = os.fork()
if pid > 0:
sys.exit(0) #exit second parent
except OSError, e:
sys.stderr.write("fork #2 failed: (%d) %s"\n % (e.errno, e.strerror) )
sys.exit(1)
#the process is now daemonized, redirect standard file descriptors
for f in sys.stdout, sys.stderr: f.flush()
si = file(stdin, 'r')
so = file(stdout, 'a+')
se = file(stderr, 'a+')
os.dup2(si.fileno(), sys.stdin.file())
os.dup2(so.fileno(), sys.stdout.file())
os.dup2(se.fileno(), sys.stderr.file())
#end def
def mod_5_watcher():
start_time = time.time()
end_time = start_time + 20
while time.time() < end_time:
now = time.time()
if int(now) % 5 == 0:
sys.stderr.write('Mod 5 at %s \n' %now)
else:
sys.stdout.write('No Mod 5 at %s \n' %now)
time.sleep(1)
#end def
if __name__ == '__main__':
#daemonize(stout='/tmp/stdout.log', stderr='/tmp/stderr.log')
daemonize()
mod_5_watcher()
九。保持数据的一致
数据一致性实际上是指, 对数据进行一定格式的保存以便以后使用。根据保存的数据关系,可以分为“简单序列化”和“关系序列化”。
对于简单序列化,可以使用python的pickle库;另外一个库是shelve;
YAML代表了“yet another markup language”是一种用来保存,恢复和更新数据的纯文本格式;ZODB代表了“Zope 对象数据库”。
关系型序列化的工具是SQLite,他是“软件库,实现了自保持,无服务器, 零配置, transactional SQL数据库引擎”, 可以解释为
数据库引擎与执行代码属于同一进程,数据被保存在一个文件中(不是分散在其他不同的地方), 不需要服务器支持。
要使用SQLite功能,首先要创建数据库, 一个sql脚本文件, 如下 simple.sql, 配合一个简单的指令就可以创建一个数据库,
BEGIN;
CREATE TABLE "person"(
"id" integer NOT NULL PRIMARY KEY,
"name" text NULL,
"address" text NULL,
"age" integer NULL
)
;
COMMIT;
命令>>sqlite3 simple.db < simple.sql 创建数据库。在取得数据库的连接后, 可以方便地使用SQL语句对数据库进行操作。
另外, 一种新的对数据库的操作模式ORM(object-RelationalMapping)正在成为流行。在ORM
中一个对象可以与表中的行表一一对应。