70

I have some custom commands.

This works:

subprocess.Popen(['python'], stdout=subprocess.PIPE) 

But if I have my own system commands like deactivate, I get that error

Traceback (most recent call last): File "runner2.py", line 21, in <module> main() File "runner2.py", line 18, in main subprocess.Popen(['deactivate',], stdout=subprocess.PIPE) File "/usr/lib/python2.6/subprocess.py", line 633, in __init__ errread, errwrite) File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory 

Let alone I need to execute this under my sandbox virtualenv.

2
  • 2
    Maybe python is not on the PATH environment variable when your script runs. Try setting the full path to python, i.e. /usr/bin/python. Commented Mar 29, 2012 at 23:44
  • 1
    Can you explain what you're trying to accomplish? I suspect that the child shell you're launching with subprocess hasn't "sourced" the virtualenv activation script, and it's not inherited from the parent Python process (assuming that's where you're running it from). Commented Mar 29, 2012 at 23:45

5 Answers 5

148

Try add an extra parameter shell=True to the Popen call.

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

3 Comments

Worked for me, but why?
@YMomb: deactivate is a shell function. To run it, you need a shell. Though it is pointless to try to run it in a new shell (the new shell probably won't have it defined until venv/bin/activate is called and the child normally can't modify its parent environment anyway if OP hopes to deactivate the current virtualenv set in the parent shell. It is the same reason why subprocess.call('cd') raises "No such file or directory" and it can be fixed using shell=True and it would be equally pointless.See Why is cd not a program?
It didn't work for me. The same script is working fine when executed on shell, but gives error on subprocess. The error is : " python3: can't open file '$SDE/install/lib/python3.6/site-packages/p4testutils/bf_switchd_dev_status.py': [Errno 2] No such file or directory " What may be the issue?
61

Just a note. shell=True was likely the correct solution to the o.p., since they did not make the following mistake, but you can also get the "No such file or directory" error if you do not split up your executable from its arguments.

import subprocess as sp, shlex sp.Popen(['echo 1']) # FAILS with "No such file or directory" sp.Popen(['echo', '1']) # SUCCEEDS sp.Popen(['echo 1'], shell=True) # SUCCEEDS, but extra overhead sp.Popen(shlex.split('echo 1')) # SUCCEEDS, equivalent to #2 

Without shell=True, Popen expects the executable to be the first element of args, which is why it fails, there is no "echo 1" executable. Adding shell=True invokes your system shell and passes the first element of args to the shell. i.e. for linux, Popen(['echo 1'], shell=True) is equivalent to Popen('/bin/sh', '-c', 'echo 1') which is more overhead than you may need. See Popen() documentation for cases when shell=True is actually useful.

3 Comments

This version of the error can occur if you forget to put commas between the string literals, as Python will concatenate them: sp.Popen(['echo' '1']) # FAILS
it should be import shlex as shlex is its own python standard package.
You will even get this error if the command (first arg) has a space in it. For example, this will fail: sp.Popen(['echo ', '1']) Notice the space right after "echo"... very easy to miss.
5

You have to give the full path to your program deactivate and then it the subprocess module should be able to find it.

Comments

0

I'm spawning subprocesses like that:

SHUTDOWN_CMD = os.path.sep.join(["c:", "windows", "system32", "shutdown.exe"]) def abortShutdown(): os.spawnv(os.P_NOWAIT, SHUTDOWN_CMD, [SHUTDOWN_CMD, '/A']) time.sleep(3) 

I'm not using subprocess since Python 2.5 does not support it. I had to use use the FULL path to have it working and I guess you also have to use the full path to your custom commands.

Comments

0

Late to the show because this kind of strange behavior happens in some environment. So I have a setup where I have cmake installed as a portable version. I set the path on a command prompt temporarily so that it doesn't override any existing versions for the user. Strangely , I observe that while typing cmake spawns cmake , calling subprocess popen for cmake doesn't work in THIS environment but WORKS in ALL OTHER setups.. The solutions I found is give full path as is already discussed here or ensure I already set the paths in the Sys environment variable PATH permanently... I had to go with latter due to some DEV constraints.

By the way Shell=true works but I already need the current shell and I pipe the results elsewhere.. so that isn't an option

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.