【问题标题】:python subprocess output to list or filepython子进程输出到列表或文件
【发布时间】:2012-02-11 10:05:59
【问题描述】:

我想在 Python 3 中运行以下 bash 命令:

ls -l

我知道我可以做到以下几点:

from subprocess import call
call(['ls', '-l'])

如何将此输出保存到文件中,或将其放入列表或集合中?

[-rw-r--r--]  [1] [name]  [staff]   [426] [14 Jan 21:52] [HelloWorld.class]
[-rw-r--r--@] [1] [name]  [staff]   [107] [14 Jan 21:51] [HelloWorld.java]
...
etc.

我希望能够直接访问特定信息,然后将其添加到集合中,但我不知道会列出多少项。

任何提示、sn-ps 或示例都会很有帮助。

【问题讨论】:

  • 如果您想访问文件/目录信息,您可能需要检查内置的os 库:documentation

标签: python python-3.x subprocess


【解决方案1】:

使用 >= python3.5 你可以使用subprocess.run:

ls_lines = subprocess.run(['ls', '-l'], stdout=PIPE).stdout.splitlines()

使用 >= python2.7 或 >= python3.0 你可以使用subprocess.check_output:

ls_lines = subprocess.check_output(['ls', '-l']).splitlines()

在python2.7之前,需要使用较低级别的api,涉及的比较多。

ls_proc = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
ls_proc.wait()
# check return code
ls_lines = ls_proc.stdout.readlines()

【讨论】:

    【解决方案2】:

    访问ls -l 输出中的信息的一种方法是解析它。例如,csv.DictReader 可用于将每一列映射到字典中的一个字段:

    import subprocess
    import csv
    
    process = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
    stdout, stderr = process.communicate()
    
    reader = csv.DictReader(stdout.decode('ascii').splitlines(),
                            delimiter=' ', skipinitialspace=True,
                            fieldnames=['permissions', 'links',
                                        'owner', 'group', 'size',
                                        'date', 'time', 'name'])
    
    for row in reader:
        print(row)
    

    上面的代码将为ls -l输出中的每一行打印一个字典,例如:

    {'group': '<group_name>',
     'name': '<filename>',
     'links': '1',
     'date': '<modified_date>',
     'time': '<modified_time>',
     'owner': '<user_name>',
     'permissions': '-rw-rw-r--',
     'size': '<size>'}
    

    【讨论】:

    • 我得到:` 文件“ip4.py”,第 16 行打印行 ^ SyntaxError: invalid syntax`
    • @user969617 是的,抱歉,这是针对 python 2.x 的,而不是针对您所要求的 python 3 的。我已经更新了适用于 python 3 的代码。
    • 这看起来很有希望!!!我的下一个问题(请告诉我,这是我使用 python 的第二天)是如何访问每个字典中的信息。我需要给他们唯一的名字吗?假设我想用电子表格交叉引用日期。
    • @user969617 无需为字典命名。您可以将它们存储在列表中,并通过索引和字典访问列表:rows[0]['name']
    • 谢谢你的代码在解析 hadoop fs -ls 方面也非常好!!!!!!!!!
    【解决方案3】:

    如果你真正想要的是列出一个目录,不如使用os.listdir

    import os
    files = os.listdir('/path/to/dir')
    for file in files:
        print(file)
    

    【讨论】:

    • 我实际上想列出机场表,但我想我会用一个简单的例子。实际输出将是call(['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport', '-s'])
    【解决方案4】:

    了解 Popen。你要求的套装

    import subprocess
    proc = subprocess.Popen(['ls','-l'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    myset=set(proc.stdout)
    

    或者做类似的事情

    for x in proc.stdout : print x
    

    stderr 也一样

    您可以使用

    检查进程的状态
    proc.poll() 
    

    或等待它以

    终止
    proc.wait()
    

    还读过

    read subprocess stdout line by line

    【讨论】:

      【解决方案5】:
      from subprocess import Popen, PIPE
      output = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
      

      然后你可以对输出做任何你想做的事情。有关详细文档,请参阅python docs

      【讨论】:

      • 谢谢。我也试过这个,但是因为缺少格式而感到困惑......我习惯用 bash 和 awk 做事,打印输出然后使用 awk '{print $n;}' 可以让你进入列,awk NR=$variable 让你选择线条。我应该看哪个部分?
      • @Gary 为 Python2.7+ 指出了一个很好的方法。如果可以,请使用它:)
      猜你喜欢
      • 2014-04-22
      • 2016-03-05
      • 2011-08-29
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多