1

I have a program with two different versions on this computer. I can't get rid of the older one because I don't have root access, but I put the newer one first in 'bin' in my home directory (which is the first thing in my $PATH)

I tried calling it with Python's Popen

Popen(['clingo'...]...)

and it worked fine

But then I needed to set an environment variable before calling it so I renamed 'clingo' to 'run_clingo' in the bin directory and replaced it with a script:

# File: ~/bin/clingo
export LD_LIBRARY_PATH=/usr/local/gcc4.8.1/lib64:$LD_LIBRARY_PATH
run_clingo $@

When I run 'clingo' from terminal, it works fine, but Python Popen calls the older version (which is later on the PATH).

How can I get Popen to call the right one? Why does changing an executable to a script cause Popen to search elsewhere?

11
  • Is your script in fact missing its shebang? If so, how is the system to know what executable is needed to run it? Commented Mar 7, 2014 at 17:34
  • My script has no shebang. What should I put there? Why? Commented Mar 7, 2014 at 18:12
  • You can set environment variables in the Popen() call via the env= keyword argument. Commented Mar 7, 2014 at 18:16
  • unrelated: you probably want "$@" instead $@. Commented Mar 7, 2014 at 19:18
  • You need shebang for the Python script if you want to run it as executable. If there's none, OS will assume it's shell script and run it using what the user has in /etc/passwd. Shebang has no effect if you run the script by calling python path/to/script. Your question does not seem like problem is there, though, since in that case your script would probably fail completely and strangely, not "call the older version". Commented Mar 7, 2014 at 19:29

2 Answers 2

2

Add shebang #!/bin/sh at the very top of ~/bin/clingo and run:

$ chmod +x ~/bin/clingo

to make the file executable.

Popen() calls os.execvp() to execute a program. Its behaviour differs from your shell that emulates execvp(): if there is no the shebang (!#.. at the top) in the script then the shell reruns it as a shell script but Python's os.execvp() runs the next file in PATH instead.

Sign up to request clarification or add additional context in comments.

1 Comment

@dspyz: what happens if you call subprocess.check_call([os.path.expanduser("~/bin/clingo)])
1

Wild guess is that Popen does not use the same PATH as your terminal. I would check the shebang line (#!) sometimes people put env -i python there, which explicitly asks fro empty, i.e. default environment.

Note that subprocess.call is the recommended way, not using the Popen directly.

6 Comments

No, it's using the same path. I tried adding env -i python and it didn't change anything. Also, if that were the case, it wouldn't explain why it works when I call the executable directly (as opposed to calling a script). I need to use Popen rather than call because I need to pass to p.stdin I tried printing out the path os.environ['PATH'] just to check and it is the same
call in essence is just Popen().wait() i.e., neither is "better" (or more recommended) than the other. It depends on your needs what to use.
I was referring to the doc: The recommended approach to invoking subprocesses is to use the following convenience functions for all use cases they can handle. ... how "much recommended" you consider that depends on you :)
"for all use cases they can handle"
@J.F.Sebastian ...and since I don't know what the use case is or why exactly OP wants to launch the program from Python script in the first place, I add the note to remind of the convenience functions.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.