Jen
Jen

Reputation: 1328

Python subprocess.run does not work when called from the same directory

Suppose following directory structure with two simple scripts

dir/
├── main.py
└── sub_routine.py

main.py:

#!/usr/bin/env python3

from subprocess import run
from pathlib import Path

my_dir = Path(__file__).parent
run([my_dir / "sub_routine.py"])

sub_routine.py:

#!/usr/bin/env python3

print("Hello there!")

When I run main.py from ancestor directory of dir it works properly:

~$ python3 ./dir/main.py
Hello there!

However, when I run it from dir it fails:

~$ cd dir
~/dir$ python3 ./main.py
...
FileNotFoundError: [Errno 2] No such file or directory: PosixPath('sub_routine.py'): PosixPath('sub_routine.py')

Why? And how can I ensure this will work regardless of where it's called from?

Upvotes: 4

Views: 935

Answers (2)

Silvan Kohler
Silvan Kohler

Reputation: 26

I would use this: (or Lukors answer)

path = Path(__file__)
print(str(path.parent.absolute()) + "/" + "sub_routine.py")

Or with os.path:

path = os.path.abspath(__file__)
print(os.path.dirname(path))

Upvotes: 0

Lukor
Lukor

Reputation: 1707

The problem is that pathlib strips any leading ./ from your path, which results in sub_routine.py instead of ./sub_routine.py. Subprocess therefore searches for an executable in your $PATH, which it of course cannot find. If there is a directory before it, say dir/sub_routine.py, it recognizes it as a path relative to your current directory and therefore works as expected.

The easiest solution is probably to use pathlib to convert the path to an absolute one: (my_dir / "sub_routine.py").absolute()

Upvotes: 3

Related Questions