相当于在Ruby和Perl中使用Python的反引号是什么?也就是说,在Ruby中,我可以这样做:
foo = `cat /tmp/baz`
Python中的等效语句是什么样的?我已经尝试过了,os.system("cat /tmp/baz")
但这会将结果放入标准输出,并向我返回该操作的错误代码。
Answers:
output = os.popen('cat /tmp/baz').read()
`...`
简直与Ruby相当(捕获stdout,将stderr传递通过)-一个例外:Ruby允许在$?
事后确定进程的退出代码;在Python中,据我所知,您必须为此使用subprocess
模块的功能。
最灵活的方法是使用subprocess
模块:
import subprocess
out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)
capture_output
是在Python 3.7中引入的,对于较旧的版本,check_output()
可以代替使用特殊功能:
out = subprocess.check_output(["cat", "/tmp/baz"])
如果需要细粒度的控制,还可以手动构造子过程对象:
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
所有这些功能都支持关键字参数,以自定义子流程的执行方式。例如shell=True
,如果您需要扩展诸如的文件名之类的功能,则可以通过外壳执行该程序*
,但这带有局限性。
subprocess.run()
(我不知道是否值得这样做)Popen()
。
某事是对的。您也可以使用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))
从Python 3.5开始,推荐的方法是使用subprocess.run
。从Python 3.7开始,要获得与您描述的相同的行为,可以使用:
cpe = subprocess.run("ls", shell=True, capture_output=True)
这将返回一个subprocess.CompletedProcess
对象。到stdout的输出将是in cpe.stdout
,到stderr的输出将是in cpe.stderr
,它们都是bytes
对象。您可以解码输出以str
使用来获取对象,cpe.stdout.decode()
或通过传递text=True
给来获取subprocess.run
:
cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)
在后一种情况下,cpe.stdout
和cpe.stderr
都是str
对象。
text=True
参数取回str而不是字节。
最简单的方法是使用命令包。
import commands
commands.getoutput("whoami")
输出:
'bganesan'
我正在使用
(6:0] $ python-版本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。查看子流程的文档字符串后,我替换了
[“ prog”,“ arg”]
与
“程序arg”
并获得了所需的外壳扩展行为(la Perl的`prog arg`)
打印subprocess.Popen(“ ls -ld / tmp / v *”,stdout = subprocess.PIPE,shell = True).communicate()[0]
我前一段时间不使用python,因为我对做等效于perl`cmd ...`的困难感到恼火。我很高兴发现Python使这变得合理。
这在python3中不起作用,但是在python2中,您可以str
使用自定义__repr__
方法进行扩展,该方法调用shell命令并按如下方式返回它:
#!/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`