代码之家  ›  专栏  ›  技术社区  ›  416c6578616e646572204d6f72656e

使用子进程popen运行list命令字符串并获取输出

  •  3
  • 416c6578616e646572204d6f72656e  · 技术社区  · 6 年前

    我正试图在这样的python脚本中运行多个UNIX命令

    import subprocess
    
    
    cmds = ['sleep 3', 'uptime','time ls -l /']
    
    
    p = subprocess.Popen(cmds,stdout=subprocess.PIPE,shell=True)
    
    
    while p.poll() is None:
        time.sleep(0.5)
    
    
    tempdata = p.stdout.read()
    
    
    
    print(tempdata)
    

    然而,我的输出并不包含所有的输出,而且似乎没有运行所有的命令。设置shell=False也会导致错误。

    Traceback (most recent call last):
      File "task1.py", line 32, in ?
        p = subprocess.Popen(commands,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False)
      File "/usr/lib64/python36/subprocess.py", line 550, in __init__
        errread, errwrite)
      File "/usr/lib64/python36/subprocess.py", line 996, in _execute_child
        raise child_exception
    OSError: [Errno 2] No such file or directory
    
    3 回复  |  直到 6 年前
        1
  •  3
  •   FMc TLP    6 年前

    当你创建一个新的进程时,你不会给它一个要运行的命令列表;相反,你通过了一个 单一命令 --或者作为字符串(带 shell=True )或者作为参数列表(带有 shell=False ).

    import subprocess
    
    cmds = ['sleep 1', 'uptime', 'ls -l /']
    
    for cmd in cmds:
        stdout = subprocess.check_output(cmd, shell=True)
        print('\n# {}'.format(cmd))
        print(stdout)
    

    如果你只是想收集stdout, subprocess.check_output() 可能比 Popen() --但这两种方法都会奏效,这取决于你需要对这个过程做什么。

        2
  •  1
  •   Paula Thomas    6 年前

    你的问题是“睡眠3”导致了你从回溯中得到的错误,当我删除它的工作原理时。

        3
  •  1
  •   zvone    6 年前

    为了实现这一切:

    cmds = ['sleep 3', 'uptime','time ls -l /']
    

    你必须为每一个问题打电话给popen:

    for cmd in cmds:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    
        while p.poll() is None:
            time.sleep(0.5)
    
        output = p.stdout.read()
    

    或者更简单:

    for cmd in cmds:
        output = subprocess.check_output(cmd, stdout=subprocess.PIPE, shell=True)
    

    第二个问题:这将捕获写入标准输出的所有输出。要捕获stderr,请将其重定向到 subprocess.PIPE