起步
人生苦短,我用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()