user1012451
user1012451

Reputation: 3433

Popen error: "[Errno 2] No such file or directory" when calling shell function

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.

Upvotes: 70

Views: 100205

Answers (5)

Sreejith. D. Menon
Sreejith. D. Menon

Reputation: 11

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

Upvotes: 0

Anthony Kong
Anthony Kong

Reputation: 40644

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

Upvotes: 147

Mark Woodward
Mark Woodward

Reputation: 938

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.

Upvotes: 61

katzenversteher
katzenversteher

Reputation: 810

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.

Upvotes: 0

Senthil Kumaran
Senthil Kumaran

Reputation: 56831

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

Upvotes: 5

Related Questions