如何在Python程序内从命令行获取数据?

38

我想在Python脚本中运行命令行程序并获取输出。

如何获取foo显示的信息,以便我可以在我的脚本中使用它?

例如,我从命令行调用foo file1,它会打印出:

Size: 3KB
Name: file1.txt
Other stuff: blah
我该如何获取文件名,例如执行代码 filename = os.system('foo file1') 后得到文件名?

6个回答

36

使用subprocess模块:

import subprocess

command = ['ls', '-l']
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.IGNORE)
text = p.stdout.read()
retcode = p.wait()

那么你可以对变量text进行任何想做的操作:正则表达式,分割等。

subprocess.Popen的第二个和第三个参数是可选的,可以被移除。


3
应使用['foo', 'file1', 'file2', ...]作为command参数。+1。 - Fred Foo
谢谢!所以foo的输出都是文本...现在我该怎么从中获取文件名呢?它像一个数组或者其他什么东西,我可以通过text[1]来获取吗?还是我可以通过搜索"Name:"来找到它?或者从第二行第七个字符开始一直到换行符结束? - user1058492
1
看看re模块,编写一个简单的正则表达式将其提取出来 pat = re.compile(r'Name:\s+(.*)$') m = pat.search(text) if m: m.group(1)(您需要添加一些换行符) - koblas
1
subprocess和PIPE应该在2.4中存在 - http://docs.python.org/release/2.4/lib/node227.html 忽略的stderr缺失。 - koblas
10
"module"对象没有属性"Ignore"。 - Hardik Gajjar
显示剩余3条评论

6

通过你的Python脚本调用工具并获取输出最简单的方法是使用标准库中的subprocess模块。请查看subprocess.check_output

>>> subprocess.check_output("echo \"foo\"", shell=True)
'foo\n'

如果您的工具从不可信来源获取输入,请确保不使用shell=True参数。


1
@PrakashPandey 这个问题已经在这里得到了解答:https://dev59.com/hmAg5IYBdhLWcg3wlbxh - NOhs

2

这通常是一个bash脚本的主题,您可以在Python中运行:

#!/bin/bash
# vim:ts=4:sw=4

for arg; do
    size=$(du -sh "$arg" | awk '{print $1}')
    date=$(stat -c "%y" "$arg")
    cat<<EOF
Size: $size
Name: ${arg##*/}
Date: $date 
EOF

done

编辑:如何使用:打开伪终端,然后复制粘贴以下内容:

cd
wget http://pastie.org/pastes/2900209/download -O info-files.bash

在 Python 2.4 中:

import os
import sys

myvar = ("/bin/bash ~/info-files.bash '{}'").format(sys.argv[1])
myoutput = os.system(myvar) # myoutput variable contains the whole output from the shell
print myoutput

1
我对Bash一无所知。我该如何在Python中使用它? - user1058492
这个解决方案仅适用于Linux,如果您有Cygwin http://en.wikipedia.org/wiki/Cygwin,则也适用于Windows。 如果您使用的是Windows或者想要一个便携式的解决方案,请查看我的新帖子。 - Gilles Quénot

2
请参考 https://docs.python.org/3/library/subprocess.html#subprocess.run
from subprocess import run
o = run("python q2.py",capture_output=True,text=True)
print(o.stdout)

输出将被编码

from subprocess import run
o = run("python q2.py",capture_output=True)
print(o.stdout)

基础语法
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)

在这里,输出不会被编码 只是一个提示


1
在Python中,您可以将带有空格、子引号和换行符的普通OS命令传递到subcommand模块中,以便我们可以解析响应文本,如下所示:
  1. 将以下代码保存为test.py:

    #!/usr/bin/python
    import subprocess
    
    command = ('echo "this echo command' + 
    ' has subquotes, spaces,\n\n" && echo "and newlines!"')
    
    p = subprocess.Popen(command, universal_newlines=True, 
    shell=True, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE)
    text = p.stdout.read()
    retcode = p.wait()
    print text;
    
  2. 然后像这样运行它:

    python test.py 
    
  3. 输出结果如下:

    this echo command has subquotes, spaces,
    
    
    and newlines!
    
如果这对你不起作用,可能是与Python版本或操作系统有关的问题。我在此示例中使用的是Ubuntu 12.10上的Python 2.7.3。

1

这是一个纯Python的便携式解决方案:

import os
import stat
import time

# pick a file you have ...
file_name = 'll.py'
file_stats = os.stat(file_name)

# create a dictionary to hold file info
file_info = {
    'fname': file_name,
    'fsize': file_stats [stat.ST_SIZE],
    'f_lm': time.strftime("%m/%d/%Y %I:%M:%S %p",time.localtime(file_stats[stat.ST_MTIME])),
}


print("""
Size: {} bytes
Name: {}
Time: {}
 """
).format(file_info['fsize'], file_info['fname'], file_info['f_lm'])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接