【问题标题】:Possibility to process a list of commands with subprocess.Popen for python3.7可以使用 subprocess.Popen for python3.7 处理命令列表
【发布时间】:2020-03-03 13:50:18
【问题描述】:

我想将应用到多个 url 的 curl 命令的内容写入一个文件,例如我有

 days = [f'from-{x+1}d-to-{x}'for x in range(5, 0, -1)]

 urls = [f'https:\\example.com?{day}/data' for day in days]

 command = [f'curl {url}' for url in urls]

 command

['curl https:\\example.com?from-6d-to-5/data', 'curl https:\\example.com?from-5d-to-4/data', 'curl https:\\example.com?from-4d-to-3/data', 'curl https:\\example.com?from-3d-to-2/data', 'curl https:\\example.com?from-2d-to-1/data']

我正在尝试将其全部写入一个文件:

content = subprocess.Popen(([x for x in command]), shell = True, text = True, stdout = subprocess.PIPE).communicate()
 file_name = open('file_1', 'a') 
 file_name.write(str(content))

但看起来 subprocess.Popen 只执行第一个 curl 命令,因为我在控制台中只能看到一个输出:

% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 12591 0 12591 0 0 20931 0 --:--:-- --:--:-- --:--:-- 20915

有没有办法用 subprocess.Popen 执行多个命令?我想应该有与要卷曲的 url 数量相同数量的控制台输出

【问题讨论】:

    标签: python curl subprocess popen


    【解决方案1】:

    在Python中可以直接使用urllib,一般不需要使用subprocess/curl:

    import urllib.request
    
    days = [f'from-{x+1}d-to-{x}'for x in range(5, 0, -1)]
    urls = [f'https://example.com?{day}/data' for day in days]
    
    for url in urls:
        with urllib.request.urlopen(url) as response:
           print(response.read())
    

    【讨论】:

    • 有单行吗?还是responses = [urllib.request.urlopen(url) for url in urls] file.write([response.read() for response in responses])
    【解决方案2】:

    来自官方文档:

    subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)

    在新进程中执行子程序。在 POSIX 上,该类使用 os.execvp()-like 行为来执行子程序。在 Windows 上, 该类使用 Windows CreateProcess() 函数。论据 Popen如下。

    args 应该是一系列程序参数,或者是单个字符串 或类似路径的物体。默认情况下,要执行的程序是第一个 args 中的项目,如果 args 是一个序列。如果 args 是一个字符串,则 解释取决于平台,如下所述。见 shell 和可执行参数与 默认行为。除非另有说明,否则建议通过 args 作为一个序列。

    Popen() 只希望创建一个子进程。所以,第一个命令被考虑,其他的可能被认为是额外的参数。

    正如@Maurice 所回答的,您可以使用urllib 来获取URL 响应。如果您仍想为此目的使用子流程,则可能需要进行更改,例如

    responses = [str(subprocess.Popen(x.split(" "), shell = True, text = True, stdout = subprocess.PIPE).communicate()) for x in commands]
    
    file_name = open('file_1', 'a')
    file_name.writelines(responses)
    

    如果您要处理大量 URL,这可能不是一个好的选择。

    【讨论】:

    • 感谢您的回复!我也会检查这个选项
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    相关资源
    最近更新 更多