【问题标题】:Python - Subprocess, character limit, split/slice string based on a certain occurrence of a characterPython - 基于某个字符出现的子进程、字符限制、拆分/切片字符串
【发布时间】:2016-04-08 05:10:01
【问题描述】:

subprocess 在 Python 中的字符限制为 32,000 个字符左右。我使用子进程打开一个 exe 并向其传递一系列命令,并且正在突飞猛进地清除字符限制。

我的解决方法是将命令字符串一分为二并调用subprocess 两次。我知道我可以按如下方式对字符串进行切片:

commands = '-a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 299@0000:55:01=1 -a 10.162.5.5 599@0000:55:01=0 -a 10.162.5.5 699@0000:55:01=0 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 499@0000:55:01=1 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 399@0000:55:01=0 -a 10.162.5.5 799@0000:55:01=34'

print(commands[:len(commands)/2])

print(commands[len(commands)/2:])

不幸的是,每个命令都采用某种格式:-a 10.162.5.5 799@0000:55:01=34 例如,直接拆分是行不通的,因为我可以将单个命令切成两半。

另一个想法是尝试以某种模式拆分字符串:

commands.split(' -')[commands.count('-')/2]

返回序列中的中间完成命令。

【问题讨论】:

  • 使用文件。如果您的命令超过 32000 个字符,那么您确实应该执行其他操作。你在调用什么程序?
  • 是否将命令保存到一个新的记事本文件中,然后让子进程读取该文件?这是一个自定义的内部程序,我的程序重置了一块具有大量设置的硬件。我为单个板检查了 32,000 多个字符,而被测设备最多可以有 24 个板。
  • 子进程只是调用一个外部程序。如果程序清楚地接受命令行参数,但它应该能够从某种文本文件中读取命令。在不了解程序的情况下很难提供准确的解决方案,但如果它需要 600,000+ 个字符,那么它就不是命令行程序!
  • subprocess 本身没有限制。对命令行的大小实施任何限制取决于操作系统。正如@Mark 所说,如果您需要在命令行上输入数千个字符,那么您就做错了。调查您的命令是否接受文件中的选项或通过其标准输入等。

标签: python string split subprocess slice


【解决方案1】:
def execute_command(commands):
"""
Execute the commands sent in the 'commands' parameter using the program
specified in the 'program' parameter.
:param commands: A command or sequence of commands
"""
#If the command string is greater than 31,000 characters
if len(commands) > 31000:
    print(len(commands))
    #Find all indices of '-' which represent the start of a new command
    index_start_command = [match.start() for match in re.finditer(re.escape('-'), commands)]
    #split the command string into two, do this by counting the number of times '-' occcurs, half it
    #and return the index of that occurance from the start list.
    commands_one = commands[:index_start_command[commands.count('-')/2]]
    commands_two = commands[index_start_command[commands.count('-')/2]:]
    subprocess.Popen([program, commands_one]).communicate()
    subprocess.Popen([program, commands_two]).communicate()
else:
    subprocess.Popen([program, commands]).communicate()

我设法将一些东西放在一起,它可以满足我的需求并且似乎有效。我想我会把它放在其他可能会撞到墙上的人身上。

【讨论】:

    【解决方案2】:

    如果您的所有命令都以-a 命令开关开头,您可以将其用作拆分每个命令的快速而肮脏的方式:

    import re
    re.findall( "-a[^-]*", commands )
    

    虽然上面不是超级理想的,因为如果遇到连字符(例如如果有任何负数),它会提前分解命令。这是一种更强大的方法,它还可以处理其他单字母命令行开关(例如,-b-c 等):

    import itertools
    import re
    starts = [match.start() for match in re.finditer( "-[a-z]", commands )]
    commandList = [commands[start:end] for start, end in itertools.zip_longest( starts, starts[1:] )]
    

    以上内容是为 Python 3.x 编写的。如果您使用的是 Python 2.6+,您需要将 zip_longest 替换为 izip_longest。查看如何调用可执行文件,您可能希望一次批处理多个命令以减少重复调用可执行文件的开销。您可以将命令重复连接到某个预定长度,也可以修改可执行文件以接受某种包含命令的批处理文件(很可能是更好的选择)。

    【讨论】:

    • 感谢您的回复。我认为将命令连接到一定长度可能是一个很好的方向。您的另一个建议也是一个很好的建议,并且之前已经提出过建议,所以我会研究一下。感谢您的回复:)
    猜你喜欢
    • 2011-11-28
    • 2017-02-15
    • 2019-12-17
    • 1970-01-01
    • 2015-04-28
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    相关资源
    最近更新 更多