2011-03-21 130 views
4

由于某些原因,我将bash脚本翻译成python。在Python中做shell反引号?

Python是功能更强大,但是,它是更困难这样的代码简单的bash代码:

MYVAR = `grep -c myfile` 

与Python我必须先定义一个反引号功能可能是:

def backquote(cmd,noErrorCode=(0,),output=PIPE,errout=PIPE): 
    p=Popen(cmd, stdout=output, stderr=errout) 
    comm=p.communicate() 
    if p.returncode not in noErrorCode: 
     raise OSError, comm[1] 
    if comm[0]: 
     return comm[0].rstrip().split('\n') 

很无聊!

是否有Python的味道(IPython?),它很容易产生进程并获取输出?

回答

8

在Python 2.7或以上,有subprocess.check_output()这基本上是你在做什么之后。

+1

++,不知道这个函数 – 2011-03-21 12:18:02

2

已定义此backquote函数,您可以从程序以及交互式shell(IPython等)中一次又一次地调用它。

没有直接的方法来在Python中使用这种“反引号”,恕我直言,有一个很好的理由。 Python以其可读性而闻名,并且在语言中具有这样的构造会鼓励不可读的“脚本”代码。话虽如此,backquote可能不是返回子进程输出的函数的最具描述性的名称。

+0

+1我的想法正好。 @Eric:定义函数时遇到的问题是什么,称之为“反引用”或任何你喜欢的,并在需要时导入它? – 2011-03-21 12:00:35

4

os.subprocess documentation介绍如何更换后引号:

output=`mycmd myarg` 
==> 
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0] 
+0

这基本上是OP在做什么,而且还检查返回值并返回一行行... – 2011-03-21 12:00:41

+0

来自RHEL6用户的投票。 – 2018-02-06 11:38:13

0

正如安德烈所说的那样,你应该使用subprocess.Popen - 但无需扩展打字 - 您可以在一个单独的文件做到这一点, 说“helper.py”你在你的脚本导入:

from subprocess import Popen, PIPE 

def r(cmd_line): 
    return Popen(cmd_line.split(), stdout=PIPE).communicate()[0] 

并在您的其他文件,你可以做到这

from helper import r 

print r("ls -l") 
print r("pwd") 
r("tar czvf new_tarball.tar.gz %s" % path_to_archive) 

请注意,如果你要通过空格 参数传递给shell命令这里面简单的方式是行不通的 - 就像一个“我的文档”的参数 - 在这种情况下 ,要么明确使用POPEN,或增强它可以处理它的帮助函数,所以 。用“\”弱化转义的空白将被 忽略,我在那里使用split

+0

使用shlex.split而不是string.split来避免引用问题。 – 2014-06-29 12:45:58