Python调用系统函数:pexcept模块

Python 2016-03-11

起步

人生苦短,我用python!最近涉猎也是越来越广了。需要创建ftp用户,然而创建用户是需要root的权限才能执行的,更是需要后续输入,好在有pexcept可以实现自由交互

举个栗子

要确定pexpect模块已安装:sudo pip install pexpect 看一个用sudo权限touch一个文件:

#!/usr/bin/env python
# coding=utf-8
import pexpect

cmd = "sudo touch sudo_touch"
passwd = '***'

run = pexpect.spawn(cmd)
try:
    run.sendline(passwd)
    ouput = run.read()
    print ouput
except:
    print 'Error'

简化可以是:

pexpect.spawn('sudo touch sudo_touch').sendline("***")

函数解释

run()函数

函数run可以用来运行命令,相当于os.system()函数,原型:run(command,timeout=-1,withexitstatus=False,events=None, extra_args=None,logfile=None, cwd=None, env=None),与os.system()不同,run可以方便的同时获取命令的输出结果和输出状态:

from pexpect import *
(command_output, exitstatus) = run ('ls -l /bin', withexitstatus=1)

spawn()类

类原型:

class spawn:
    def __init__(self,command,args=[],timeout=30,maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None)

spawn是Pexpect模块主要的类,用以实现启动子程序,它有丰富的方法与子程序交互从而实现用户对子程序的控制。它主要使用 pty.fork() 生成子进程,并调用 exec() 系列函数执行 command 参数的内容。

child = pexpect.spawn ('/usr/bin/ftp', [])
child = pexpect.spawn ('/usr/bin/ssh', ['user@example.com'])
child = pexpect.spawn ('ls', ['-latr', '/tmp'])

记录日志

child = pexpect.spawn('some_command')
fout = file('mylog.txt','w')
child.logfile = fout

# 如果不需要记录向子程序输入的日志,只记录子程序的输出
child = pexpect.spawn('some_command')
child.logfile = sys.stdout

expect()函数

为了控制spawn()的对象产生的子程序,等待其产生的特定输出,做出特定的响应,需要用到expect方法,函数原型为:expect(self, pattern, timeout=-1, searchwindowsize=None) pattern可以是正则表达式

异常

try:
    index = pexpect (['good', 'bad'])
        if index == 0:
            do_something()
        elif index == 1:
            do_something_else()
    except EOF:
        do_some_other_thing()
except TIMEOUT:
    do_something_completely_different()

避免异常:

index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) 
if index == 0: 
    do_something()
elif index == 1:
    do_something_else()
elif index == 2:
    do_some_other_thing()
elif index == 3:
    do_something_completely_different()

send()函数

child.send('a')
child.sendline('bb')
child.sendcontrol('c') # 发送ctrl+c

snedline()send()函数会额外输入一个回车符

结尾

我想添加用户的功能思路应该有了。

#!/usr/bin/env python
# coding=utf-8

import pexpect
import random

class FtpAddUser():

    ROOT_PASS = 'admin123' #sudo 密码
    CROOT_LIST = '/etc/vsftpd.chroot_list' # 允许跨越目录
    USER_DIR = '/etc/vsftp_user_conf/' # 用户相关配置文件夹

    @staticmethod
    def runCmdRoot(cmd, params = None):
        run = pexpect.spawn(cmd)
        try:
            for line in params:
                #time.sleep(0.5) # 休眠,确保以下输出是有效的
                run.expect(':|:')
                run.sendline(line)
        except:
            print 'Error'
        return run.read()

    @staticmethod
    def create_password(length = 6, prex = ''):
        word=[x for x in 'abcdefghijklmnopqrstuvwxyz0123456789']
        return prex + ''.join(random.sample(word, length))

    def __init__(self, username = None, password = None):
        if username == None:
            username = FtpAddUser.create_password(8, 'ftpuser')
        if password == None:
            password = FtpAddUser.create_password(8)
        # 确保添加的用户名可用
        while True:
            cmd = "/bin/grep '^{}' /etc/passwd".format(username)
            if FtpAddUser.runCmdRoot(cmd, []) == '': # 如果该用户名不存在,说明可添加
                break
            username = FtpAddUser.create_password(8, 'ftpuser')
        self.username = username
        self.password = password

    def addUser(self):
        params = [FtpAddUser.ROOT_PASS, self.password, self.password, '', '', '', '','', 'y']
        #cmd = 'sudo adduser -g ftp -s /sbin/nologin {}'.format(self.username)
        cmd = 'sudo adduser {}'.format(self.username)
        FtpAddUser.runCmdRoot(cmd, params)
        # 设置用户禁止登陆shell
        cmd = 'sudo usermod -s /sbin/nologin {}'.format(self.username)
        FtpAddUser.runCmdRoot(cmd, [FtpAddUser.ROOT_PASS,])
        cmd = 'sudo usermod -g ftp {}'.format(self.username)
        FtpAddUser.runCmdRoot(cmd, [FtpAddUser.ROOT_PASS,])
        self.addUserConf()

    def addUserConf(self):
        cmd = "sudo touch /home/{}/这是{}用户默认的ftp目录.txt".format(self.username, self.username)
        FtpAddUser.runCmdRoot(cmd, [FtpAddUser.ROOT_PASS,])
        # 设置用户配置,登陆目录设为/home/username
        with open('{}{}'.format(FtpAddUser.USER_DIR, self.username), 'w') as f:
            f.write('local_root=/home/{}'.format(self.username))
        #设置文件归属为root用户
        cmd = 'sudo chown root:root {}{}'.format(FtpAddUser.USER_DIR, self.username)
        FtpAddUser.runCmdRoot(cmd, [FtpAddUser.ROOT_PASS,])

    def show(self):
        print 'username is {}'.format(self.username)
        print 'password is {}'.format(self.password)

if __name__ == "__main__":
    test = FtpAddUser()
    test.addUser()
    test.show()

本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧