在Python中运行Bash命令

时间:2010-11-23 12:38:09

标签: python bash

在我的本地机器上,我运行一个包含此行的python脚本

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
os.system(bashCommand)

这很好用。

然后我在服务器上运行相同的代码,我收到以下错误消息

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "/usr/bin/cwm", line 48, in <module>
from swap import  diag
ImportError: No module named swap

所以我所做的就是插入一个print bashCommand打印我,而不是终端中的命令,然后用os.system()运行它。

当然,我再次得到错误(由os.system(bashCommand)引起)但在错误发生之前它会在终端中输出命令。然后我只是复制了那个输出并在终端上做了一个复制粘贴,然后按回车键就可以了......

有没有人知道发生了什么?

9 个答案:

答案 0 :(得分:248)

请勿使用os.system。它已被弃用,有利于subprocess。来自docs:“此模块旨在替换几个较旧的模块和函数:os.systemos.spawn”。

就像你的情况一样:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

答案 1 :(得分:38)

使用子流程

调用它
import subprocess
subprocess.Popen("cwm --rdf test.rdf --ntriples > test.nt")

你得到的错误似乎是因为服务器上没有交换模块,你应该在服务器上安装swap然后再次运行脚本

答案 2 :(得分:18)

您可以使用bash程序,使用参数-c执行命令:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
output = subprocess.check_output(['bash','-c', bashCommand])

答案 3 :(得分:9)

你可以使用&#39; subprocess&#39;但我一直觉得它不是&#39; Pythonic&#39;这样做的方式。所以我创建了Sultan(无耻插件),可以轻松运行命令行功能。

https://github.com/aeroxis/sultan

答案 4 :(得分:8)

根据错误,您在服务器上缺少名为 swap 的程序包。这个/usr/bin/cwm需要它。如果您使用的是Ubuntu / Debian,请使用aptitude安装python-swap

答案 5 :(得分:2)

要在没有外壳的情况下运行命令,请将命令作为 list 传递,并使用[subprocess]在Python中实现重定向:

#!/usr/bin/env python
import subprocess

with open('test.nt', 'wb', 0) as file:
    subprocess.check_call("cwm --rdf test.rdf --ntriples".split(),
                          stdout=file)

注意:末尾没有> test.ntstdout=file实现了重定向。


要在Python中使用Shell运行命令,请将命令作为 string 传递并启用shell=True

#!/usr/bin/env python
import subprocess

subprocess.check_call("cwm --rdf test.rdf --ntriples > test.nt",
                      shell=True)

这里是外壳负责输出重定向(命令中> test.nt)。


要运行使用bashism的bash命令,请显式指定bash可执行文件,例如,将其指定为emulate bash process substitution

#!/usr/bin/env python
import subprocess

subprocess.check_call('program <(command) <(another-command)',
                      shell=True, executable='/bin/bash')

答案 6 :(得分:1)

您也可以使用'os.popen'。 示例:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

输出:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

答案 7 :(得分:0)

这样做的pythonic方法是使用subprocess.Popen

subprocess.Popen获取一个列表,其中第一个元素是要运行的命令,后跟任何命令行参数。

举个例子:

import subprocess

args = ['echo', 'Hello!']
subprocess.Popen(args) // same as running `echo Hello!` on cmd line

args2 = ['echo', '-v', '"Hello Again"']
subprocess.Popen(args2) // same as running 'echo -v "Hello Again!"` on cmd line

答案 8 :(得分:0)

subprocess.Popen()os.system()更受青睐,因为它提供了更多的控制和可见性。但是,如果您发现subprocess.Popen()太冗长或过于复杂,则peasyshell是我在上面编写的一个小型包装程序,可以轻松地与Python中的bash交互。

https://github.com/davidohana/peasyshell