getopt参数解析笔记
背景
在 Python 中,使用 getopt 模块进行命令行参数解析是常见的需求。在编写脚本时,正确地定义参数选项对于确保程序正常运行至关重要。这是一个用于检测安卓软件版本的脚本一部分,有些用法和笔记分享给大家
问题描述
在某个脚本中,使用 getopt 解析命令行参数时,发现如果指定参数选项但不传递参数就会导致后续所有参数无法正确接收参数。发现参数定义还分两种情况。
所有参数选项必须带参数的定义传参
opts, args = getopt.getopt(sys.argv[1:], "e:a:d:o:n:", ["expected=", "actual=", "device", "out", "sn="])
-d/-o都不需要参数的传参定义
opts, args = getopt.getopt(sys.argv[1:], "e:a:dd:oo:n:", ["expected=", "actual=", "device", "out", "sn="])
#or
opts, args = getopt.getopt(sys.argv[1:], "e:a:d o n:", ["expected=", "actual=", "device", "out", "sn="])
原因分析
参数需求:
使用冒号(:)表示该选项后面需要跟随参数。例如,-e 选项后需要一个期望的版本号。
将 -d 和 -o 定义为 d: 和 o: 表示它们后面需要参数,而实际上它们是布尔开关,不需要参数。
解决方案
通过将 -d 和 -o 重复定义为 dd: 和 oo:,也不需要参数。
通过将 -d 和 -o 去除引号定义为 d 和 o ,定义为布尔开关,不需要参数。
示例代码
以下是完整的示例代码,展示如何正确解析命令行参数:
import sys
import getopt
if __name__ == '__main__':
print("parameter:")
try:
opts, args = getopt.getopt(sys.argv[1:], "e:a:dd:oo:n:", ["expected=", "actual=", "device", "out", "num="])
except getopt.GetoptError as err:
print(f"Error: {err}")
sys.exit(1)
expected_version = None
actual_version = None
device = False
out_param = False
device_num = None
print(f"opts: {opts}") # 打印解析的选项
for opt, arg in opts:
if opt in ('-e', '--expected'):
expected_version = arg
print(f"Expected version: {expected_version}")
elif opt in ('-a', '--actual'):
actual_version = arg
print(f"Actual version: {actual_version}")
elif opt in ('-d', '--device'):
device = True
print("Device mode selected.")
elif opt in ('-o', '--out'):
out_param = True
print("Output mode selected.")
elif opt in ('-n', '--sn'):
device_num = arg
# 后续逻辑...
实际运行
运行命令时,可以使用以下格式:
python3 ./build_scripts/ParseDLToolsVersion/checkComponentVersions2.py -o -e ./build_scripts/release_info/prebuild_version_expected.txt -a ./o
utversion.txt
parameter:
opts: [('-o', ''), ('-e', './build_scripts/release_info/prebuild_version_expected.txt'), ('-a', './outversion.txt')]
总结
去掉冒号:确保 -d 和 -o 不带冒号,以便它们被视为布尔开关。
理解参数定义:通过理解 getopt 的参数定义规则,可以避免常见的解析错误,确保命令行参数能够被正确处理。