spiral01
spiral01

Reputation: 545

Python: absolute path issue

I have several files stored in a folder called controlFiles. The path to this folder is Users/Desktop/myproject/controlFiles.

I am attempting to run a subprocess command in my python script with the following code:

def codeml(codeml_location, control_location):
    runPath = codeml_location + '/codeml'
    for file in os.listdir(control_location):
        ctlPath = os.path.abspath(file)
        subprocess.call([runPath, ctlPath])

The script's function is to run a command line tool called codeml, with the first argument being the location of the codeml executable, and the second being a folder of control files that codeml uses. When I run this script codeml runs but I get the error:

error when opening file /Users/Desktop/myproject/subtree.39.tre.ctl
tell me the full path-name of the file? 

My confusion comes from the fact that the controlFiles folder is not within that path, yet it still identifies the files within the folder.

To check I was entering the correct control_location argument I edited the code as such:

def codeml(codeml_location, control_location):
    runPath = codeml_location + '/codeml'
    for file in os.listdir(control_location):
        print os.path.abspath(file)

Running this printed all the files in the controlFiles folder, but again without the folder within the paths. Here is a sample of the print out:

/Users/Desktop/myproject/subtree.68.tre.ctl
/Users/Desktop/myproject/subtree.69.tre.ctl
/Users/Desktop/myproject/subtree.70.tre.ctl
/Users/Desktop/myproject/subtree.71.tre.ctl

To run the function my control location argument is:

control_location = /Users/Desktop/myproject/controlFiles

A final point is that my working directory in the terminal is /Users/Desktop/myproject and this is because this is the location of my Click project. Why are the files being picked up but not the folder containing them?

Upvotes: 2

Views: 1570

Answers (4)

jfs
jfs

Reputation: 414149

The script's function is to run a command line tool called codeml, with the first argument being the location of the codeml executable, and the second being a folder of control files that codeml uses.

if control_location is the folder of control files that codeml uses:

import os
import subprocess

def codeml(codeml_location, control_location):
    executable = os.path.join(codeml_location, 'codeml')
    subprocess.check_call([executable, control_location])

You don't need to call os.listdir() here.

Upvotes: 0

spiral01
spiral01

Reputation: 545

I managed to resolve this using:

for file in os.listdir(control_location):
        filepath = os.path.dirname(os.path.realpath(file)) 
        subprocess.call([runPath, filepath])

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

Set the cwd in the subprocess:

 for file in os.listdir(control_location):
    subprocess.call([runPath, file],  cwd=control_location)

listdir is just returning the basename, not the full path. Setting the cwd to where the files are will allow you to just pass file. If listdir can file control_location then subprocess should also have no issues.

Upvotes: 1

Daniel
Daniel

Reputation: 42748

os.listdir does list the filenames in the directory control_location not in the current working path. So you have to join the filename with the path control_location:

for file in os.listdir(control_location):
    ctlPath = os.path.abspath(os.path.join(control_location, file))

Upvotes: 3

Related Questions