下面是一些函数编程的练习:
mtping.py内容:
#!/usr/bin/env python
#coding:utf8
import os
def ping(ip):
result = os.system("ping -c2 %s &>/dev/null" %ip)
if result:
print "%s:down " % ip
else:
print "%s:up" % ip
if __name__ == "__main__":
for i in range(1,255):
ipaddr = "172.40.2.%s" % i
ping(ipaddr)
mtping2.py内容:
import os
import threading
def ping(ip):
result = os.system("ping -c2 %s &>/dev/null" %ip)
if result:
print "%s:down " % ip
else:
print "%s:up" % ip
if __name__ == "__main__":
for i in range(1,255):
ipaddr = "172.40.2.%s" % i
t = threading.Thread(target=ping,args=[ipaddr])
ping(ipaddr)
生成随机密码
方法1:用raw_input方式不推荐
#!/usr/bin/env python
#coding:utf8
import random
import string
all_chs = string.letters + string.digits
def gen_pass():
pwd = ''
num = int(raw_input("number: "))
for i in range(num):
ch = random.choice(all_chs)
pwd += ch
print pwd
if __name__ == "__main__":
gen_pass()
方法2:
#!/usr/bin/env python
#coding:utf8
import random
import string
all_chs = string.letters + string.digits
def gen_pass(num=8):
pwd = ''
for i in range(num):
ch = random.choice(all_chs)
pwd += ch
return pwd
if __name__ == "__main__":
print gen_pass(5)
print gen_pass()
print gen_pass(10)
编写 makeTextFile.py 脚本,主要要求如下:
1、编写一个程序,要求用户输入文件名
2、如果文件已存在,要求用户重新输入
3、提示用户输入数据,每行数据先写到列表中
4、将列表数据写入到用户输入的文件名中
方案
首先通过循环不断要求用户输入文件名,如果文件已经存在,要求用户输入新文件名。
然后提示用户输入文件内容,将用户的输入信息保存到一个列表中。最后将列表中的每个字符串尾部都加上行结束标志,并写入文件。
为了程序的跨平台性,可以调用 os.linesep 确定行结束标志。在 Linux 系统中,行结束标志为’
’;在 Windows 系统中,行结束标志为’
’。
#!/usr/bin/env python
#coding:utf8
import os
def get_fname():
while True:
fname = raw_input("filename: ")
if not os.path.exists(fname):
break
print "%s already exists.Try again" % fname
return fname
def get_contents():
contents = []
while True:
data = raw_input("(Enter to quit)>")
if not data:
break
contents.append(data + '
')
return contents
def wfile(fname,contents):
fobj = open(fname,'w')
fobj.writelines(contents)
fobj.close()
if __name__ == "__main__":
filename = get_fname()
lines = get_contents()
wfile(filename,lines)
在shell中,可以用这种方式实现远程改密码:
chpwd.sh内容:远程改密码
#!/bin/bash
if [ -z "$3" ];then
echo "Usage: $0 ipfile oldpass newpass"
exit 1
fi
ipfile=$1
oldpass=$2
newpass=$3
if [! -f $ipfile ];then
echo "$ipfile does not exists"
exit 2
fi
for ip in $(cat $ipfile)
do
expect <<EOF
spawn ssh root@$ip "echo $newpass | passwd --stdin root"
expect "(yes/no)?"{
send "yes
"
expect "password:"
send "$oldpass
"
} "password:" { send "$oldpass
"}
expect eof
EOF
done
执行结果:
chmod +x chpwd.sh
./chpwd.sh
./chpwd.sh ipaddr.txt redhat redhat
而在Python中,可以通过paramiko模块实现
chpwd.py内容:远程改密码
方法1:
#!/usr/bin/env python
import sys
import paramiko
def remote_comm(host,pwd,comm):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host,username='root',password=pwd)
stdin,stdout,stderr = ssh.exec_command(comm)
print stdout.read(),
print stderr.read(),
if __name__ == "__main__":
if len(sys.argv) !=4:
print "Usage: %s ipfile oldpass newpass" % sys.argv[0]
else:
ipfile = sys.argv[1]
oldpass = sys.argv[2]
newpass = sys.argv[3]
ch_pwd = "echo %s | passwd --stdin root" % newpass
fobj = open(ipfile)
for line in fobj:
ip = line.strip()
remote_comm(ip,oldpass,ch_pwd)
执行结果:
[root@host-192-168-3-6 test]# chmod +x chpwd.py
[root@host-192-168-3-6 test]# cat ipaddr.txt
192.168.3.6
root@host-192-168-3-6 test]# ./chpwd.py ipaddr.txt abc123 abc123
Changing password for user root.
passwd: all authentication tokens updated successfully.
方法2:mtchpwd.py内容:远程改密码
#!/usr/bin/env python
import sys
import paramiko
import threading
def remote_comm(host,pwd,comm):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host,username='root',password=pwd)
stdin,stdout,stderr = ssh.exec_command(comm)
print stdout.read(),
print stderr.read(),
if __name__ == "__main__":
if len(sys.argv) !=4:
print "Usage: %s ipfile oldpass newpass" % sys.argv[0]
else:
ipfile = sys.argv[1]
oldpass = sys.argv[2]
newpass = sys.argv[3]
ch_pwd = "echo %s | passwd --stdin root" % newpass
fobj = open(ipfile)
for line in fobj:
ip = line.strip()
t = threading.Thread(target=remote_comm,args=(ip,oldpass,ch_pwd))
t.start()
编写 idcheck.py 脚本,主要要求如下:
1、程序接受用户输入
2、用户输入的数据要求大于两个字符
3、判断用户输入的标识符是否合法
方案
合法标识符的要求是:
1、第一个字符必须是字母或下划线
2、其余字符可以是字母、下划线或数字
3、大小写敏感
方法1:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import string
alphas = string.letters + '_'
nums = string.digits
print 'Welcome to my id check prog'
inp = raw_input('Enter a id: ')
if inp[0] not in alphas: #判断首字符是否合法
print 'bad identifier'
else:
for otherchar in inp[1:]: #判断其余字符是否合法
if otherchar not in (alphas + nums):
print 'bad other char'
break
else: #注意此处的 else 是 for 结构的一部分
print '%s is good' % inp
执行结果:
Welcome to my id check prog
Enter a id: 123
bad identifier
方法2:
#!/usr/bin/env python
#coding:utf8
import string
first_chs = string.letters + '_'
other_chs = first_chs + string.digits
def check_id(myid):
if myid[0] not in first_chs:
print "1st char invalid."
return
for ind,ch in enumerate(myid[1:]):
if ch not in other_chs:
print "char in position:%s invalid" % (ind +2)
break
else:
print "%s is valid" % myid
if __name__ == "__main__":
myid = raw_input("id to check: ")
if myid:
check_id(myid)
else:
print "You must input an identifier."
执行结果:
id to check: 124
1st char invalid.
编写 formatoutput.py 脚本,主要要求如下:
1、提示用户输入(多行)数据
2、假定屏幕的宽度为 50,用户输入的多行数据如下显示(文本内容居中) :
方案
为了实现文本内容居中,可以在字符串的两端打印相关的“+”号和空格即可。
字符串每一侧打印的空格数可以使用屏幕宽度减去字符串长度再除以 2 得到。 这里要注
意的是如果字符串的长度为奇数,那么将会少打印一个空格。可以在做除法时,把余数保留
下来,字符串左侧打印的空格数为除法的商值,右侧打印的空格数为商值加余数
方法1:
#!/usr/bin/env python
#coding:utf8
width = 48
data = [] #定义列表用于存储用户数据
while True:
entry = raw_input('enter data(. to quit)> ')
if entry == '.':
break
data.append(entry)
print '+' + '*' * width + '+'
for item in data:
length, extra = divmod((width - len(item)) , 2)
print '+' + ' ' * length + item + ' ' * (length + extra) + '+'
print '+' + '*' * width + '+'
执行结果:
enter data(. to quit)> hello
enter data(. to quit)> great work
enter data(. to quit)> .
+************************************************+
+ hello +
+ great work +
+************************************************+
方法2:
#!/usr/bin/env python
#coding:utf8
def get_contents():
contents = []
while True:
data = raw_input("(Enter to quit)>")
if not data:
break
contents.append(data)
return contents
if __name__ == '__main__':
width = 48
lines = get_contents()
print "+%s+" %('*' * width)
for line in lines:
sp_wid,extra = divmod((width-len(line)),2)
print "+%s%s%s+" % (' ' * sp_wid,line,' ' * (sp_wid+extra))
print "+%s+" % ('*' * width)
(Enter to quit)>hello
(Enter to quit)>great work
(Enter to quit)>
+************************************************+
+ hello +
+ great work +
+************************************************+
创建用户
编写 adduser.py 脚本,主要要求如下:
1、编写一个程序,实现创建用户的功能
2、提示用户输入用户名
3、随机生成 8 位密码
4、创建用户并设置密码
5、发邮件通知用户相关信息
创建用户完成后,需要发送邮件通知。因为每封邮件的内容格式一样,只是用户名和
密码有变化,所以使用字符串模板可以很好的实现该功能。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import string
import random
import os
allChs = string.letters + string.digits
#以下三行为字符串模板的字符串
patt = """your account is created.
username: $user
password: $pwd"""
def genPwd(num = 8): #生成随机密码函数
pwd = ''
for i in range(num):
pwd += random.choice(allChs)
return pwd
if __name__ == '__main__':
username = raw_input('username: ')
password = genPwd()
os.system('useradd %s' % username)
os.system('echo %s | passwd --stdin %s' % (password, username))
t = string.Template(patt)
os.system("echo '%s' | mail -s 'create user' root" % t.substitute(user = username,pwd = password))
执行结果:
[root@host-192-168-3-6 tarena]#python adduser.py
username: alice
Changing password for user alice.
passwd: all authentication tokens updated successfully.
[root@host-192-168-3-6 tarena]# mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 2 messages 1 new
1 root Fri Jun 16 10:31 21/691 "user info"
>N 2 root Sat Jul 29 10:03 20/710 "create user"
&
Message 2:
From root@host-192-168-3-6.localdomain Sat Jul 29 10:03:55 2017
Return-Path: <root@host-192-168-3-6.localdomain>
X-Original-To: root
Delivered-To: root@host-192-168-3-6.localdomain
Date: Sat, 29 Jul 2017 10:03:52 +0800
To: root@host-192-168-3-6.localdomain
Subject: create user
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: root@host-192-168-3-6.localdomain (root)
Status: R
your account is created.
username: alice
password: IHgkunGZ
&
方法2:
#!/usr/bin/env python
#coding:utf8
import sys
import randpass2
import os
import string
contents = """username: ${username}
password: ${password}
"""
t = string.Template(contents)
def adduser(user,passwd,email):
data = t.substitute(username=user,password=passwd)
os.system("useradd %s" % user)
os.system("echo %s| passwd --stdin %s" % (passwd,user))
os.system("echo -e '%s' | mail -s 'user info' %s" % (data,email))
if __name__ == '__main__':
username = sys.argv[1]
pwd = randpass2.gen_pass()
adduser(username,pwd,'root@localhost')
执行结果:
[root@host-192-168-3-6 test]# chmod +x adduser.py
[root@host-192-168-3-6 test]# ./adduser.py jerry
Changing password for user jerry.
passwd: all authentication tokens updated successfully.
注意:randpass2模块是自定义的模块,其中的内容为:
#coding:utf8
import random
import string
all_chs = string.letters + string.digits
def gen_pass(num=8):
pwd = ''
for i in range(num):
ch = random.choice(all_chs)
pwd += ch
return pwd
if __name__ == "__main__":
print gen_pass(5)
print gen_pass()
print gen_pass(10)
用列表构建栈结构
栈是一个后进先出的结构,编写 stack.py 脚本,主要要求如下:
1、编写一个程序,用列表实现栈结构
2、需要支持压栈、出栈、查询功能
方案
列表是可变的数据类型,用它模拟栈结构非常合适。在列表的内建方法中,append()
用于向列表追加元素,pop()用于从列表中弹出元素。pop()可以接受下标作为参数,用于
弹出指定位置的元素,默认弹出的是最后一个元素。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
stack = []
def pushit(): #定义压栈函数
item = raw_input('input item: ').strip()
stack.append(item)
def popit(): #定义出栈函数
if len(stack) == 0:
print '