14. python中的脚本编程
- Python脚本接受输入
我们可以通过fileinput来进行实现输入传递
比如
with fileinput.input() as f_input:
for line in f_input: print(line, end=”) |
这种时候我们就可以如下进行脚本的使用
$ ls | ./filein.py # Prints a directory listing to stdout.
$ ./filein.py /etc/passwd # Reads /etc/passwd to stdout.
$ ./filein.py < /etc/passwd # Reads /etc/passwd to stdout.
fileinput.input 会创建并返回一个FileInput的实例,可以作为一个上下文使用
其中除了基本的输出行,还可以获取到文件名字,文件的行号
>>> with fileinput.input(‘/etc/passwd’) as f:
>>> for line in f: … print(f.filename(), f.lineno(), line, end=”) … |
- 终止程序
我一般是直接使用sys.Exit(1) 不过这里我们可以抛出一个SystemExit异常,并传递给其错误消息
raise SystemExit(‘It failed!’)
这样程序会以状态码1退出,并且消息会在sys.stderr中打印
- 给脚本规定参数,并填充help
可以利用python提供的argparse模块
import argparse
parser = argparse.ArgumentParser(description=’Search some files’) parser.add_argument(dest=’filenames’,metavar=’filename’, nargs=’*’) parser.add_argument(‘-p’, ‘–pat’,metavar=’pattern’, required=True, dest=’patterns’, action=’append’, help=’text pattern to search for’) parser.add_argument(‘-v’, dest=’verbose’, action=’store_true’, help=’verbose mode’) parser.add_argument(‘-o’, dest=’outfile’, action=’store’, help=’output file’) parser.add_argument(‘–speed’, dest=’speed’, action=’store’, choices={‘slow’,’fast’}, default=’slow’, help=’search speed’) args = parser.parse_args() # Output the collected arguments print(args.filenames) print(args.patterns) print(args.verbose) print(args.outfile) print(args.speed) |
这样我们将文件另存为 search.py
直接 python3 search.py -h
可以获取到最上面创建parser时输入的desc
并且是其他arg的详情
我们顺拜年说下每一个args的配置
在每一个arg中,dest是配置给属性的名字,metavar生成帮助信息,action指定处理逻辑
如果在nargs中指定了* 则代表搜集所有剩余命令行到这个参数列表中
Action中支持的动作有 store ,store_true 设置为一个boolean标志
这样我们添加了多个参数之后,就可以使用parser.parse()方法,会返回一个结果实例
- 用户输入账号密码
如果希望和用户进行交互,比如输入一个账号名
则可以直接使用内置的input函数
User = input(‘Enter your username’)
获取到用户名
或者使用自带的getpass模块,来弹出密码提示
passwd = getpass.getpass()
- 获取终端大小
这一点直接利用 os.get_terminal_size() 即可做到
- 执行外部命令并获取到输出
如果希望执行系统的命令,可以使用subprocess.check_output(),传入一个数组
import subprocess
out_bytes = subprocess.check_output([‘netstat’,’-a’])
默认返回一个字节字符串
且只会获取到标准输出的值,如果希望获取到标准输出和错误输出,可以使用stderr参数
out_bytes = subprocess.check_output([‘cmd’,’arg1′,’arg2′],
stderr=subprocess.STDOUT) |
或者利用except捕捉 subprocess.CalledProcessError获取returncode或者output亦可
- 复制或者移动文件
如果希望移动文件或者目录
Python中其实提供shutil来进行操作,比如shutil.copy shutil.copytree shutil.move
分别去复制文件,复制文件夹,以及移动文件
import shutil
# Copy src to dst. (cp src dst) shutil.copy(src, dst) # Copy files, but preserve metadata (cp -p src dst) shutil.copy2(src, dst) # Copy directory tree (cp -R src dst) shutil.copytree(src, dst) # Move src to dst (mv src dst) shutil.move(src, dst) |
copy_tree() 可以在拷贝文件夹的时候选择性的忽略某些文件后者目录
def ignore_pyc_files(dirname, filenames):
return [name in filenames if name.endswith(‘.pyc’)] shutil.copytree(src, dst, ignore=ignore_pyc_files) |
- 创建和解压文件夹
也可以使用shutil 模块,make_archive() 以及 unpack_archive()
Unpack负责解锁
>>> shutil.unpack_archive(‘Python-3.3.0.tgz’)
make_archive 第二个参数是输出格式,可以通过get_archive_formats获取到输出格式
>>> shutil.make_archive(‘py33′,’zip’,’Python-3.3.0′)
- 查找文件
利用os.walk() 函数,可以获取到一个目录下的所有文件,这里我们书写一个函数
import os
def findfile(start, name): for relpath, dirs, files in os.walk(start): if name in files: full_path = os.path.join(start, relpath, name) print(os.path.normpath(os.path.abspath(full_path))) if __name__ == ‘__main__’: findfile(sys.argv[1], sys.argv[2]) |
其返回一个三元组,分别是目录的相对路径,目录下的所有文件夹,目录下的文件
这里我们还使用os.path.join 来拼接路径,以及abspath来绝对值化路径
nrompath 来返回正常路径