36、Python命令行工具的高级应用与配置

Python命令行工具的高级应用与配置

1. 多参数选项的使用模式

默认情况下, optparse 中的选项只能接受一个参数,但可以将参数数量设置为其他值。下面是一个示例,创建一个类似 ls 的版本,用于同时显示两个目录的内容:

#!/usr/bin/env python
import optparse
import os

def main():
    p = optparse.OptionParser(description="Lists contents of two directories",
                                prog="pymultils",
                                version="0.1a",
                                usage="%prog [--dir dir1 dir2]")
    p.add_option("--dir", action="store", dest="dir", nargs=2)
    options, arguments = p.parse_args()
    if options.dir:
        for dir in options.dir:
            print "Listing of %s:\n" % dir
            for filename in os.listdir(dir):
                print filename
    else:
        p.print_help()

if __name__ == '__main__':
    main()

操作步骤

  1. 运行上述脚本时,如果只给 --dir 选项提供一个参数,会得到错误提示:
[ngift@Macintosh-8][H:10238][J:0]# python multiple_option_args.py --dir /tmp
Usage: pymultils [--dir dir1 dir2]

pymultils: error: --dir option requires 2 arguments
  1. 当提供正确数量的参数时,会显示两个目录的内容:
[ngift@Macintosh-8][H:10239][J:0]# python multiple_option_args.py --dir /tmp /Users/ngift/Music
Listing of /tmp:

.aksusb
FLEXnet
helloworld
hsperfdata_ngift
ics10003
ics12158
ics13342
ics14183
ics15392
icssuis501
MobileSync.lock.f9e26440fe5adbb6bc42d7bf8f87c1e5fc61a7fe
summary.txt
Listing of /Users/ngift/Music:

.DS_Store
.localized
iTunes

2. 结合Python与Unix命令行工具

可以通过Python包装现有的命令行工具并更改其API,或者将一个或多个Unix命令行工具与Python混合使用,来创建新的命令行工具。

2.1 Kudzu使用模式:用Python包装工具

有时候,现有的命令行工具可能不符合我们的需求,比如需要太多选项或者参数顺序不符合我们的使用习惯。可以使用Python来改变工具的行为,这就是“Kudzu”设计模式。

snmpdf 命令为例,正常运行 snmpdf 命令的输出如下:

[ngift@Macintosh-8][H:10285][J:0]# snmpdf -c public -v 2c example.com 
Description              size (kB)            Used       Available Used%
Memory Buffers             2067636          249560         1818076   12%
Real Memory                2067636         1990704           76932   96%
Swap Space                 1012084              64         1012020    0%
/                         74594112        17420740        57173372   23%
/sys                             0               0               0    0%
/boot                       101086           20041           81045   19%

下面是用Python包装 snmpdf 命令的示例代码:

#!/usr/bin/env python
import optparse
from subprocess import call

def main():
    p = optparse.OptionParser(description="Python wrapped snmpdf command",
                                prog="pysnmpdf",
                                version="0.1a",
                                usage="%prog machine")
    p.add_option("-c", "--community", help="snmp community string")
    p.add_option("-V", "--Version", help="snmp version to use")
    p.set_defaults(community="public",Version="2c")
    options, arguments = p.parse_args()
    SNMPDF = "snmpdf"
    if len(arguments) == 1:
        machine = arguments[0]
        #Our new snmpdf action
        call([SNMPDF, "-c", options.community, "-v",options.Version, machine])
    else:
        p.print_help()

if __name__ == '__main__':
    main()

操作步骤

  1. 上述脚本使用 optparse 模块创建选项,并设置默认参数。
  2. 通过 subprocess.call 调用 snmpdf 命令,并传递相应的参数。

2.2 混合Kudzu设计模式:用Python包装工具并改变行为

可以不仅用Python包装Unix工具,还可以改变工具的基本行为。以下是使用Python的生成器过滤 snmpdf 命令结果的示例:

#!/usr/bin/env python
import optparse
from subprocess import Popen, PIPE
import re

def main():
    p = optparse.OptionParser(description="Python wrapped snmpdf command",
                                prog="pysnmpdf",
                                version="0.1a",
                                usage="%prog machine")
    p.add_option("-c", "--community", help="snmp community string")
    p.add_option("-V", "--Version", help="snmp version to use")
    p.set_defaults(community="public",Version="2c")
    options, arguments = p.parse_args()
    SNMPDF = "snmpdf"
    if len(arguments) == 1:
        machine = arguments[0]
        #We create a nested generator function
        def parse():
            """Returns generator object with line from snmpdf"""
            ps = Popen([SNMPDF, "-c", options.community,
                        "-v",options.Version, machine],
                        stdout=PIPE, stderr=PIPE)
            return ps.stdout

        #Generator Pipeline To Search For Critical Items
        pattern = "9[0-9]%"
        outline = (line.split() for line in parse()) #remove carriage returns
        flag = (" ".join(row) for row in outline if re.search(pattern, row[-1])) 
        #patt search, join strings in list if match
        for line in flag: print "%s CRITICAL" % line
        #Sample Return Value
        #Real Memory 2067636 1974120 93516 95% CRITICAL
    else:
        p.print_help()

if __name__ == '__main__':
    main()

操作步骤

  1. 运行上述脚本,会过滤 snmpdf 命令的结果,只显示使用率达到90%及以上的信息,并添加 “CRITICAL” 标志:
[ngift@Macintosh-8][H:10486][J:0]# python snmpdf_alter.py localhost
Real Memory 2067636 1977208 90428 95% CRITICAL
  1. 可以进一步扩展该脚本,搜索80%、70%的使用率并生成警告信息。

2.3 混合Kudzu设计模式:用Python包装Unix工具以生成进程

还可以通过Python包装Unix工具,使其高效地生成多个副本。以下是一个使用 dd 命令创建多个图像文件的示例:

from subprocess import Popen, PIPE
import optparse
import sys

class ImageFile():
    """Created Image Files Using dd"""
    def __init__(self, num=None, size=None, dest=None):
        self.num = num
        self.size = size
        self.dest = dest

    def createImage(self):
        """creates N 10mb identical image files"""
        value = "%sMB " % str(self.size/1024)
        for i in range(self.num):
            try:
                cmd = "dd if=/dev/zero of=%s/file.%s bs=1024 count=%s"\
                    % (self.dest,i,self.size)
                Popen(cmd, shell=True, stdout=PIPE)
            except Exception, err:
                sys.stderr.write(err)

    def controller(self):
        """Spawn Many dd Commands"""
        p = optparse.OptionParser(description="Launches Many dd",
                                    prog="Many dd",
                                    version="0.1",
                                    usage="%prog [options] dest")
        p.add_option('-n', '--number', help='set many dd',
                    type=int)
        p.add_option('-s', '--size', help='size of image in bytes',
                    type=int)
        p.set_defaults(number=10,
                        size=10240)
        options, arguments = p.parse_args()
        if len(arguments) == 1:
            self.dest = arguments[0]
            self.size = options.size
            self.num = options.number
            #runs dd commands
            self.createImage()

def main():
    start = ImageFile()
    start.controller()

if __name__ == "__main__":
    main()

操作步骤

  1. 运行上述脚本,可以设置文件的字节大小、路径和文件/进程的总数:
$ ./subprocess_dd.py /tmp/
$ 10240+0 records in
10240+0 records out
10485760 bytes transferred in 1.353665 secs (7746199 bytes/sec)
10240+0 records in
10240+0 records out
10485760 bytes transferred in 1.793615 secs (5846160 bytes/sec)
10240+0 records in
10240+0 records out
10485760 bytes transferred in 2.664616 secs (3935186 bytes/sec)
...output supressed for space....
  1. 该工具可用于测试高速光纤SAN或NAS设备的磁盘I/O性能。

3. 集成配置文件

将配置文件集成到命令行工具中,可以提高工具的可用性和可定制性。Python标准库中的 ConfigParser 模块可用于读写 .ini 格式的配置文件。

3.1 创建配置文件

创建一个名为 hello_config.ini 的配置文件,内容如下:

[Section A]
phrase=Config

3.2 集成配置文件到命令行工具

以下是将配置文件集成到 “Hello World” 命令行工具的示例代码:

#!/usr/bin/env python
import optparse
import ConfigParser

def readConfig(file="hello_config.ini"):
    Config = ConfigParser.ConfigParser()
    Config.read(file)
    sections = Config.sections()
    for section in sections:
        #uncomment line below to see how this config file is parsed
        #print Config.items(section)
        phrase = Config.items(section)[0][1]
        return phrase

def main():
    p = optparse.OptionParser()
    p.add_option('--sysadmin', '-s')
    p.add_option('--config', '-c', action="store_true")
    p.set_defaults(sysadmin="BOFH")
    options, arguments = p.parse_args()
    if options.config:
        options.sysadmin = readConfig()
    print 'Hello, %s' % options.sysadmin

if __name__ == '__main__':
    main()

操作步骤

  1. 运行上述脚本时,如果不提供任何选项,会使用默认值:
[ngift@Macintosh-8][H:10543][J:0]# python hello_config_optparse.py
Hello, BOFH
  1. 如果选择 --config 选项,会解析配置文件并使用其中的值:
[ngift@Macintosh-8][H:10545][J:0]# python hello_config_optparse.py --config
Hello, Config
  1. 可以设置 --config 选项的默认路径,允许用户自定义配置文件的读取位置:
p.add_option('--config', '-c', help='Path to read in config file')

总结

标准库中的 Optparse ConfigParser 模块易于使用,并且在大多数系统中都可用。如果需要编写大量命令行工具,可以探索 optparse 的高级功能,如使用回调函数和扩展 optparse 本身。还可以关注一些非标准库的相关模块,如 CommandLineApp Argparse ConfigObj

流程图

graph TD;
    A[开始] --> B[创建配置文件];
    B --> C[集成配置文件到命令行工具];
    C --> D[运行脚本];
    D --> E{是否选择 --config 选项};
    E -- 是 --> F[解析配置文件并使用其中的值];
    E -- 否 --> G[使用默认值];
    F --> H[输出结果];
    G --> H;
    H --> I[结束];

表格

工具 功能 示例代码
pymultils 同时显示两个目录的内容 示例代码
pysnmpdf 简化 snmpdf 命令的使用 示例代码
snmpdf_alter 过滤 snmpdf 命令的结果 示例代码
Many dd 使用 dd 命令创建多个图像文件 示例代码
hello_config_optparse 集成配置文件的 Hello World 工具 示例代码

4. 不同工具的使用场景与对比分析

4.1 各工具的使用场景总结

  • pymultils :适用于需要同时查看多个目录内容的场景,能提高查看效率,避免多次执行 ls 命令。
  • pysnmpdf :简化了 snmpdf 命令的使用,对于只关注机器信息,不想输入过多选项和参数的用户来说非常方便。
  • snmpdf_alter :可用于监控系统资源使用情况,能及时发现资源使用率达到临界值的情况,便于及时采取措施。
  • Many dd :用于测试存储设备的磁盘 I/O 性能,通过创建多个图像文件来模拟高负载的读写操作。
  • hello_config_optparse :展示了如何集成配置文件到命令行工具,提高工具的灵活性和可定制性,适用于需要根据不同配置运行的工具。

4.2 工具对比表格

工具名称 主要功能 依赖模块 优点 缺点
pymultils 同时显示两个目录内容 optparse, os 操作简单,可同时查看多目录 只能固定显示两个目录
pysnmpdf 简化 snmpdf 命令使用 optparse, subprocess 减少输入参数,使用方便 功能相对单一,仅简化原命令
snmpdf_alter 过滤 snmpdf 结果,标记临界信息 optparse, subprocess, re 可监控关键资源使用情况 代码相对复杂,不易理解
Many dd 生成多个 dd 进程创建图像文件 optparse, subprocess, sys 可测试磁盘 I/O 性能 可能会对磁盘造成较大压力
hello_config_optparse 集成配置文件到命令行工具 optparse, ConfigParser 提高工具可定制性 依赖配置文件,配置错误可能导致工具异常

5. 命令行工具开发的注意事项与技巧

5.1 注意事项

  • 参数处理 :使用 optparse 或其他参数解析模块时,要确保正确设置参数的类型、数量和默认值,避免因参数错误导致工具运行异常。
  • 错误处理 :在调用外部命令或进行文件操作时,要进行错误处理,避免因异常情况导致程序崩溃。例如在 Many dd 工具中,对 Popen 调用进行了异常捕获。
  • 配置文件管理 :使用 ConfigParser 读取配置文件时,不要依赖配置文件中项的顺序,因为内部使用字典存储,要通过正确的键来获取值。

5.2 技巧

  • 默认参数设置 :使用 set_defaults 方法可以方便地设置命令行工具的默认参数,减少用户输入。如在 pysnmpdf hello_config_optparse 中都使用了该方法。
  • 生成器的使用 :在需要处理大量数据或过滤数据时,使用生成器可以节省内存,提高性能。如在 snmpdf_alter 中使用生成器过滤 snmpdf 命令的结果。
  • 模块化设计 :将不同的功能封装成函数或类,提高代码的可读性和可维护性。如在 Many dd 工具中,将创建图像文件和控制进程的功能分别封装在 createImage controller 方法中。

6. 未来拓展与应用展望

6.1 工具功能拓展

  • pymultils :可以扩展为支持同时显示任意数量的目录内容,通过增加参数或循环处理来实现。
  • pysnmpdf :可以添加更多的默认参数选项,或者支持不同的 SNMP 版本和社区字符串的动态配置。
  • snmpdf_alter :可以增加更多的过滤规则,如支持多个使用率阈值的监控,并根据不同的阈值发送不同级别的警报。
  • Many dd :可以添加生成报告的功能,将磁盘 I/O 测试结果生成 PDF 报告,并通过邮件发送给相关人员。
  • hello_config_optparse :可以支持多个配置文件的读取和合并,提高配置的灵活性。

6.2 应用场景拓展

  • 自动化运维 :将这些工具集成到自动化运维脚本中,实现系统资源的自动监控和磁盘性能的定期测试。
  • 云计算环境 :在云计算环境中,使用这些工具可以方便地管理和监控虚拟机的资源使用情况和磁盘性能。
  • 物联网设备管理 :对于大量的物联网设备,可以使用这些工具进行设备资源的集中管理和监控。

流程图

graph TD;
    A[现有工具] --> B[功能拓展];
    A --> C[应用场景拓展];
    B --> D[新功能工具];
    C --> E[新应用场景工具];
    D --> F[自动化运维];
    D --> G[云计算环境];
    D --> H[物联网设备管理];
    E --> F;
    E --> G;
    E --> H;

总结

通过对多参数选项的使用、Python 与 Unix 命令行工具的结合、配置文件的集成等方面的介绍,我们了解了如何开发和优化 Python 命令行工具。这些工具不仅提高了工作效率,还增强了系统的可管理性和可维护性。在未来的开发中,我们可以根据实际需求对这些工具进行拓展和优化,使其更好地适应不同的应用场景。同时,要注意遵循开发的注意事项和运用相关技巧,提高代码的质量和性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值