相当于Python中的Bash反引号

时间:2009-09-11 13:47:53

标签: python backticks

Python中的Ruby和Perl中的反引号相当于什么?也就是说,在Ruby中我可以这样做:

foo = `cat /tmp/baz`

Python中的等效语句是什么样的?我已经尝试了os.system("cat /tmp/baz"),但是这会将结果标准化,并将该操作的错误代码返回给我。

11 个答案:

答案 0 :(得分:90)

output = os.popen('cat /tmp/baz').read()

答案 1 :(得分:82)

最灵活的方法是使用subprocess模块:

import subprocess

out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)
在Python 3.7中引入了

capture_output,对于旧版本,可以使用特殊函数check_output()

out = subprocess.check_output(["cat", "/tmp/baz"])

如果需要精细控制,也可以手动构建子进程对象:

proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()

所有这些函数都支持keyword parameters来自定义子进程的执行方式。例如,如果您需要shell=True的文件名扩展,但需要limitations附带的内容,则可以使用*通过shell执行程序。

答案 2 :(得分:26)

sth is right。您也可以使用os.popen(),但通常可以使用(Python 2.4+)子进程。

然而,与一些鼓励它的语言不同,产生子进程通常被认为是不好的形式,你可以在语言中做同样的工作。它更慢,更不可靠,并且依赖于平台。你的例子会更好:

foo= open('/tmp/baz').read()

ETA:

  

baz是一个目录,我正在尝试获取该目录中所有文件的内容

?目录上的猫给我一个错误。

如果你想要一个文件列表:

import os
foo= os.listdir('/tmp/baz')

如果您想要目录中所有文件的内容,例如:

contents= []
for leaf in os.listdir('/tmp/baz'):
    path= os.path.join('/tmp/baz', leaf)
    if os.path.isfile(path):
        contents.append(open(path, 'rb').read())
foo= ''.join(contents)

或者,如果你可以确定那里没有目录,你可以把它放在一个单行中:

path= '/tmp/baz'
foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))

答案 3 :(得分:15)

foo = subprocess.check_output(["cat", "/tmp/baz"])

答案 4 :(得分:9)

从Python 3.5开始,推荐的方法是使用subprocess.run。要获得与您描述的相同的行为,您可以使用:

output = subprocess.run("ls", shell=True, stdout=subprocess.PIPE).stdout

这将返回bytes个对象。您可能希望将.decode("ascii").decode("utf-8")附加到最后以获得str

答案 5 :(得分:6)

最简单的方法是使用命令包。

import commands

commands.getoutput("whoami")

输出:

  

'bganesan'

答案 6 :(得分:3)

import os
foo = os.popen('cat /tmp/baz', 'r').read()

答案 7 :(得分:2)

我正在使用

  

(6:0)$ python --version   Python 2.7.1

上面的一个例子是:

import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

对我来说,这无法访问目录/ tmp。查看子进程的doc字符串后,我替换了

  

[“prog”,“arg”]

  

“prog arg”

并获得了所需的shell扩展行为(一个Perl的'prog arg`)

  

print subprocess.Popen(“ls -ld / tmp / v *”,stdout = subprocess.PIPE,shell = True).communicate()[0]


我暂时退出使用python,因为我很难做到相当于perl`cmd ...`的困难。我很高兴发现Python已经做到了这一点。

答案 8 :(得分:1)

如果您使用subprocess.Popen,请记住指定bufsize。默认值为0,表示“未缓冲”,而不是“选择合理的默认值”。

答案 9 :(得分:1)

这在python3中不起作用,但在python2中,您可以使用调用shell命令的自定义str方法扩展__repr__,并返回它:

#!/usr/bin/env python

import os

class Command(str):
    """Call system commands"""

    def __repr__(cmd):
        return os.popen(cmd).read()

你可以使用

#!/usr/bin/env python
from command import Command

who_i_am = `Command('whoami')`

# Or predeclare your shell command strings
whoami = Command('whoami')
who_i_am = `whoami`

答案 10 :(得分:0)

backtick中的Python 3(`)运算符 was removed 。它与单引号一样令人困惑,并且在某些键盘上很难键入。代替backtick,使用等效的内置函数repr()