Popen错误:[Errno 2]没有这样的文件或目录

问题描述:

我有一些自定义命令。Popen错误:[Errno 2]没有这样的文件或目录

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

但是,如果我有一个像deactivate我自己的系统命令,我得到这个错误

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 

别说我需要在我的沙箱的virtualenv执行此。

+2

脚本运行时'python'不在'PATH'环境变量中。尝试设置python的完整路径,即'/ usr/bin/python'。 – 2012-03-29 23:44:24

+1

你能解释你想完成什么吗?我怀疑你用'subprocess'启动的子shell没有“源”virtualenv激活脚本,它不是从父Python进程继承的(假设这是你运行它的地方)。 – 2012-03-29 23:45:45

尝试在Popen调用中添加一个额外的参数'shell = True'。

+40

为我工作,但为什么? – YMomb 2015-03-11 17:44:27

+0

仍然不起作用 – Woeitg 2016-04-28 13:47:29

+5

@YMomb:'deactivate'是一个shell函数。要运行它,你需要一个shell。尽管尝试在一个新shell中运行它是没有意义的(新shell可能不会定义它,直到调用venv/bin/activate,并且如果OP希望通过子进程通常无法修改其父环境取消激活在父shell中设置的当前virtualenv,这与subprocess.call('cd')'提出“没有这样的文件或目录”并且可以使用'shell = True'修复的原因是一样的,毫无意义。请参阅[为什么cd不是程序?](http://unix.stackexchange.com/q/38808/1321) – jfs 2016-05-20 09:32:36

你必须给你的程序deactivate的完整路径,然后它的子进程模块应该能够找到它。

我产卵子过程那样:

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) 

我不使用子因为Python 2.5不支持它。我不得不使用完整路径来使其工作,我想你也必须使用自定义命令的完整路径。

只是一个说明。 shell=True很可能是o.p.的正确解决方案,因为它们没有犯下以下错误,但是如果你没有将它的可执行文件从其参数中分离出来,你也可以得到“No such file or directory”错误。

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 

没有shell=True,POPEN预计可执行是args来第一元件,这就是为什么它失败,不存在“呼应1”可执行文件。添加shell=True会调用您的系统shell并将args的第一个元素传递给shell。即对于Linux,Popen(['echo 1'], shell=True)相当于Popen('/bin/sh', '-c', 'echo 1'),这比您可能需要的开销更大。有关shell=True实际上有用的情况,请参见Popen() documentation

+0

如果忘记在字符串文字之间插入逗号,则会发生此版本的错误,因为Python将连接它们:'sp.Popen(['echo''1'])#FAILS' – 2017-06-19 17:08:42