Python Argparse 无法分割字符串
这件事应该很简单,但现在让我有点困扰。我设置了一个简单的命令行参数解析工具(argparse),想要在字符串中如果有减号就把它分开。听起来很简单,但当我把这些参数传给argparse时,它却显示为空。所以我想给你看看我想做的事情,以及为什么我觉得很困惑。注意:我已经明确指定它是一个字符串。使用dir和type函数时也显示为空。
import argparse
import sys
portlist = []
#Parser Arguments and Usage
parser = argparse.ArgumentParser(description='This script performs a Syn scan on a specific host with the ports that are specified by you.', usage='Specify Ports with the -p switch. Port range -p 80-200, specific port -p 80, multiple ports -p 80,443,25,22', add_help=True)
parser.add_argument('-p', action='store', dest='argPorts', help='Type ports in like follows. For a range -p 80-200, for a group of ports -p 443,80,25,22 or single port -p 80', required=True, type=str)
parser.add_argument('-d', action='store', dest='destIP', help='Type dest IP in this field. i.e. 192.168.0.5', required=True)
parser.add_argument('-t', action='store', dest='threadCount', help='Type the amount of threads to use as an integer', type=int, required=True)
if len(sys.argv)<3:
parser.print_help()
sys.exit(0)
opts = vars(parser.parse_args())
options = parser.parse_args()
argPorts = options.argPorts
destIP = options.destIP
threadCount = options.threadCount
if argPorts.find(','):
print "comma"
for p in argPorts.split(','):
portlist.append(p)
elif argPorts.find('-'):
print "range"
portlist.append(argPorts.split('-')[0])
portlist.append(argPorts.split('-')[1])
else:
print "no"
print portlist
我在命令行中这样使用它:
python test.py -t 10 -p "80-100" -d "192.168.136.131"
我想把80和100分开成两个变量。但它不工作 :(
下面的回答很棒。
这里有个很好的解释,适合像我这样的人 http://www.pythoncentral.io/how-to-see-if-a-string-contains-another-string-in-python/
2 个回答
1
你可以把处理端口的逻辑放到一个函数里,然后把这个函数作为type
传给你的add_argument('-p')
,这样还可以添加一些用户友好的错误提示,像这样:
def parse_port(port):
if port.isdigit():
return int(port)
else:
raise argparse.ArgumentTypeError(
"'{}' is not a valid port".format(port))
def parse_port_range(port_range):
range_members = port_range.split("-")
if len(range_members) != 2:
raise argparse.ArgumentTypeError(
"'{}' is not a valid port range".format(port_range))
actual_range = range(parse_port(range_members[0]),
parse_port(range_members[1]) + 1)
return actual_range
def parse_ports(port_string):
#first break commas
port_groups = port_string
if ',' in port_string:
port_groups = port_string.split(",")
#then figure out ranges and populate the set of ports
ports = set()
for port_group in port_groups:
if "-" in port_group:
port_range = parse_port_range(port_group)
ports.update(port_range)
else: # single port
ports.add(parse_port(port_group))
return list(ports)
#finally create your CLI argument
parser.add_argument('-p', dest='argPorts', type=parse_ports,
help=('Type ports in like follows. For a range -p 80-200, '
'for a group of ports -p 443,80-200,25,22 or single '
'port -p 80'))
在你调用parser.parse_args()
之后,options.argPorts
里会包含一个整数端口的列表。如果用户输入的端口有问题,就会收到一个有帮助的提示信息。
2
问题是,如果找不到搜索的字符串,.find() 方法会返回 -1。所以你不能仅仅通过是否存在来检查。
你可以试试这样的写法:
if argPorts.find(',') != -1:
...
elif argPorts.find('-') != -1:
...
我更喜欢这样的写法:
if ',' in argPorts:
print("comma")
for p in argPorts.split(','):
portlist.append(p)
elif '-' in argPorts:
print("range")
portlist.append(argPorts.split('-')[0])
portlist.append(argPorts.split('-')[1])
else:
print("no")
另外,我觉得你想要在给定一个范围时创建一个端口列表。
for port in range(int(argPorts.split('-')[0]), int(argPorts.split('-')[1])+1):
portlist.append(port)