2013-03-11 29 views
0

我有一个bash片段,我想移植到Python。它发现SVN的位置以及它是否可执行。如何在Python中使用这个bash测试构造?

SVN=`which svn 2>&1` 
if [[ ! -x $SVN ]]; then 
    echo "A subversion binary could not be found ($SVN)"   
fi 

下面是一个使用子模块在Python我当前的尝试:

SVN = Popen('which svn 2>&1', shell=True, stdout=PIPE).communicate()[0] 
Popen("if [[ ! -x SVN ]]; then echo 'svn could not be found or executed'; fi", shell=True) 

这不,因为虽然我有SVN的位置保存在Python的本地命名空间的工作,我可以”从Popen访问它。

我也试图组合成一个POPEN对象:

Popen("if [[ ! -x 'which svn 2>&1']]; then echo 'svn could not be found'; fi", shell=True) 

,但我得到这个错误(不用说,看起来很笨重)

/bin/sh: -c: line 0: syntax error near `;' 
/bin/sh: -c: line 0: `if [[ ! -x 'which svn 2>&1']]; then echo 'svn could not be found'; fi' 

有一个测试的Python版本构造“-x”?我认为这将是理想的。其他解决方法也将受到赞赏。

由于

+1

[此网站](http://ubuntuforums.org/showthread.php?t=1457094)提供了一个代码段,看起来像'commands.getoutput(“如果[-x MYFILE] \ n然后回声真\ NFI“)'。然而,由于您仍在调用Bash,因此这很难“移植到Python”。 – Kos 2013-03-11 07:14:04

+1

'os.stat'可以给你关于给定文件的一些信息,比如它的权限,但是我认为你仍然需要为它建立一个“可执行的当前用户”测试。 – Kos 2013-03-11 07:16:17

+1

您可以先将bash命令存储为字符串,以便您可以将它与变量SVN连接起来?然后将其传递给Popen()... – Jeff 2013-03-11 07:16:58

回答

1
SVN = Popen('which svn 2>&1', shell=True, stdout=PIPE).communicate()[0] 
str="if [[ ! -x " + SVN + " ]]; then echo 'svn could not be found or executed'; fi" 
Popen(str, shell=True) 
+1

这是非常低效的,它分叉了很多,并且让僵尸进程四处流窜。 – LtWorf 2013-03-11 08:08:14

4

这是最简单的解决方案:

path_to_svn = shutil.which('svn') 
is_executable = os.access(path_to_svn, os.X_OK) 

shutil.which是在Python 3.3新; this answer中有一个polyfill。如果你真的想要,你也可以从Popen中获取路径,但这不是必需的。

这里是os.access的文档。

+0

'os.access()'是多余的。 'shutil.which()'默认已经检查'X_OK'。 – jfs 2013-03-13 04:11:14

1

没有必要使用哪一个,你可以尝试运行svn而无需参数,如果它工作,这意味着它在那里。

try: 
    SVN = subprocess.Popen('svn') 
    SVN.wait() 
    print "svn exists" 
except OSError: 
    print "svn does not exist"