19

I have a python script that is under this directory:

work/project/test/a.py

Inside a.py, I use subprocess.POPEN to launch the process from another directory,

work/to_launch/file1.pl, file2.py, file3.py, ...

Python Code:

subprocess.POPEN("usr/bin/perl ../to_launch/file1.pl") 

and under work/project/, I type the following

[user@machine project]python test/a.py,

error "file2.py, 'No such file or directory'"

How can I add work/to_launch/, so that these dependent files file2.py can be found?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
pepero
  • 191
  • 1
  • 1
  • 5
  • 6
    you can try usin cwd argument in Popen: http://stackoverflow.com/questions/1685157/python-popen-working-directory-argument – Ayrat Mar 29 '12 at 13:16
  • In Python use `import os` then `os.chdir('/tmp/yourdirectory')` That will set the current directory for your python script. – Eric Leschinski Jan 04 '14 at 22:30

3 Answers3

18

Your code does not work, because the relative path is seen relatively to your current location (one level above the test/a.py).

In sys.path[0] you have the path of your currently running script.

Use os.path.join(os.path.abspath(sys.path[0]), relPathToLaunch) with relPathToLaunch = '../to_launch/file1.pl' to get the absolute path to your file1.pl and run perl with it.

EDIT: if you want to launch file1.pl from its directory and then return back, just remember your current working directory and then switch back:

origWD = os.getcwd() # remember our original working directory

os.chdir(os.path.join(os.path.abspath(sys.path[0]), relPathToLaunch))
subprocess.POPEN("usr/bin/perl ./file1.pl") 
[...]

os.chdir(origWD) # get back to our original working directory
eumiro
  • 207,213
  • 34
  • 299
  • 261
  • i am sorry, but file1.pl can be found and run. because I am running the python under the "/work/project" directory, not under "work/project/test" directory. The problem is the file2, file 3, which are called by file1.pl cannot be found. – pepero Sep 21 '10 at 16:58
  • Well, then it seems to be a Perl problem in your file1.pl? – eumiro Sep 21 '10 at 18:42
  • Hi, eumiro, thank you for your answer. However, it cannot solve the problem, because all the other files file1.pl, etc. they are not under current python working directory, instead they are all assuming under /..../to_launch/ directory. e.g. inside file1.pl, it directly call "./file3.py", and I cannot change this path in file1.pl. To make a short sum up, Let me rephase my question: in python, how to call another program, which is running under another working directory? – pepero Sep 22 '10 at 08:30
  • Ah OK, so if you cannot change file1.pl and this file1.pl has to call other programs using relative paths, then you have to change yourself into file1.pl's directory using Python's `os.chdir(path_of_file1_pl)` and run file1.pl as if it was in the local directory, i.e. `./file1.pl`. – eumiro Sep 22 '10 at 08:41
  • thank you eumiro. chdir is one solution. but honestly, I am not confident with this one, because i have to launch several projects under A/, B/,... one by one. so this implies, from my python parent process, I first os.chdir(/work/to_launchA/), subprocess.POPEN("usr/bin/perl ./file1.pl"), and then change back to original WD, and repeat this for B, C, etc. My concern is: Can I change back to original WD at any time as I want? Do I have to wait B or C to finish? Is there other approach, such as setting some variables for A, B, etc, and their WD can be automatically found without using chdir. – pepero Sep 22 '10 at 09:41
  • Then I would look into the direction of the `env` parameter of the `subprocess.POPEN` function call: `subprocess.POPEN("/usr/bin/perl ./file1.pl", env={"PWD": os.path.join(os.path.abspath(sys.path[0]), relPathToLaunch)})` – eumiro Sep 22 '10 at 09:48
  • Hi, eumiro, do you mean the function "subprocess.POPEN" can be used to explicitly define the working directory of the subprocess? If so, it would be very good solution. – pepero Sep 22 '10 at 09:53
  • http://docs.python.org/library/subprocess.html - they tell it so – eumiro Sep 22 '10 at 09:54
  • HI, eumiro, and all, I tried the env parameter approach, it does not work at all. specifically, I use subprocess.Popen("/usr/bin/perl ./start_ws.pl", env = {"PWD": "/.../work/to_launchA/"}, shell=True); I even changed the "PWD" to "PATH", no ./start_ws.pl found. And if I changed to subprocess.Popen("/usr/bin/perl /.../work/to_launchA/start_ws.pl", env = {"PWD": "/.../work/to_launchA/"}, shell=True), it can find start_ws.pl (of course, I give the absolute path), but still cannot find other related files (which implies, the env parameter is not working). python official documentation is wrong? – pepero Sep 22 '10 at 16:15
  • so, what is the hell way to call subprocesses, which are under different working directory? really nasty. – pepero Sep 22 '10 at 16:19
3

Use paths relative to the script, not the current working directory

os.path.join(os.path.dirname(__file__), '../../to_launch/file1.pl)

See also my answer to Python: get path to file in sister directory?

Community
  • 1
  • 1
Adam Byrtek
  • 12,011
  • 2
  • 32
  • 32
  • HI, Adam, the problem is file1.py will need to call other files, which are all under another working directory. please see my comment above. Thank you all the same for your post. – pepero Sep 22 '10 at 16:40
1

You could use this code to set the current directory:

import os
os.chdir("/path/to/your/files")
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
anijhaw
  • 8,954
  • 7
  • 35
  • 36
  • well, ok, i tried os.chdir, and this command seems to change my current working directory. The problem is that I have to lauch several subprocesses, and each subprocess will call the code in respective directories, such as work/to_launch/A/file1.pl, file2.py, etc. and work/to_launch/B/file1.pl., file2, file3. ... Also if i use chdir, how do I change back? i mean inside my program, I frequently inject these commands to change back and forth. it is not very good. I suppose python should have some way which easily could be used to add dependent directory. – pepero Sep 21 '10 at 17:20
  • also, I am launching several children processes, so I am not sure how this should work for parent and children processes – pepero Sep 21 '10 at 17:46
  • so suppose file1.pl has abs path /a/b/c/file1.pl so run your command like this os.chdir("a/b/c/") and then execute file1.pl I think it should work. – anijhaw Sep 21 '10 at 18:38
  • HI, anijhaw, as I said above, I do not know when to change back to the original WD. especially, my python is just a launching program, process A, process B, will continue running. so how and when can i change back, without affecting A? if I keep waiting A, how can I start to change to WD of B to launch B? personally I think, either I go wrong or python is not sufficient to do this(0.0...001% chance). – pepero Sep 22 '10 at 16:34