0

I have a bash snippet I would like to port over to Python. It finds where SVN is located and whether it is executable.

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

Here is my current attempt in Python using the subprocess module:

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)

This does not work because while I do have the location of SVN saved in the local namespace of Python, I can't access it from Popen.

I also tried combining into one Popen object:

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

But I get this error (and needless to say, looks very unwieldy)

/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'

Is there a Python version of the test construct "-x"? I think that would be ideal. Other workarounds would be appreciated as well.

Thanks

imagineerThat
  • 5,293
  • 7
  • 42
  • 78
  • 1
    [this site](http://ubuntuforums.org/showthread.php?t=1457094) provides a snippet that looks like `commands.getoutput("if [ -x myfile ]\nthen echo true\nfi")`. However this is hardly "porting to Python" since you're still invoking Bash. – Kos Mar 11 '13 at 07:14
  • 1
    `os.stat` can give you some information about a given file, such as its permissions, but I think you'd still need to build up a "executable for current user" test on top of that. – Kos Mar 11 '13 at 07:16
  • 1
    can you store the bash command as a string first, so that you can concatenate it with variable SVN? then pass that to Popen()... – Jeff Mar 11 '13 at 07:16
  • 2
    Found it, the 'executable for current user' can be done using [`os.access`](http://docs.python.org/2/library/os.html#os.access). – Kos Mar 11 '13 at 07:19

3 Answers3

4

This is the simplest solution:

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

shutil.which is new in Python 3.3; there's a polyfill in this answer. You could grab the path from Popen too if you really want, but that's not necessary.

And here are the docs for os.access.

Community
  • 1
  • 1
Kos
  • 70,399
  • 25
  • 169
  • 233
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)
Jeff
  • 12,147
  • 10
  • 51
  • 87
1

There is no need to use which, you can already try to run svn without parameters and if it works it means it's there.

try:
    SVN = subprocess.Popen('svn')
    SVN.wait()
    print "svn exists"
except OSError:
    print "svn does not exist"
LtWorf
  • 7,286
  • 6
  • 31
  • 45