Python Windows subprocess.Popen不带shell的批处理文件=True

Python Windows subprocess.Popen不带shell的批处理文件=True,python,windows,shell,subprocess,Python,Windows,Shell,Subprocess,我有一个运行lessc(与npm安装-g less一起安装)的函数: 在不使用shell=True的情况下,如何使lessc运行?将文件更改为lessc.bat,或创建调用lessc的.bat文件。这样,Windows会将该文件识别为批处理文件并正确执行 除此之外,您可能还需要设置cwd,具体取决于.bat文件的位置。来自和: 运行批处理文件或基于控制台的可执行文件不需要shell=True 已经是这样了 因此,让我们试试: 其中lessc实际告诉 C:\Users\myname\AppData

我有一个运行
lessc
(与
npm安装-g less一起安装)的函数:


在不使用
shell=True
的情况下,如何使
lessc
运行?

将文件更改为lessc.bat,或创建调用lessc的.bat文件。这样,Windows会将该文件识别为批处理文件并正确执行

除此之外,您可能还需要设置cwd,具体取决于.bat文件的位置。

来自和:

运行批处理文件或基于控制台的可执行文件不需要
shell=True

已经是这样了

因此,让我们试试:

其中lessc
实际告诉

C:\Users\myname\AppData\Roaming\npm\lessc
C:\Users\myname\AppData\Roaming\npm\lessc.cmd
这意味着,要执行的文件是
lessc.cmd
,而不是一些
.bat
文件。事实上:

>>> import subprocess
>>> subprocess.Popen([r'C:\Users\myname\AppData\Roaming\npm\lessc.cmd'])
<subprocess.Popen object at 0x035BA070>
>>> lessc: no input files

usage: lessc [option option=parameter ...] <source> [destination]
然后你可以写:

import subprocess
subprocess.Popen([where('lessc')])

你能在不使用
shell=True
的情况下显式调用二进制文件的完整路径名吗?@kragniz:
lessc
是一个批处理文件(这实际上可能是问题所在),当我使用完整路径运行它时,会发生相同的错误。错误是由子流程模块本身还是由批处理脚本生成的?您可以在Popen上添加
cwd=r'c:\path\to\script\'
参数call@JBernardo:子流程
模块。因此,如果不编辑脚本本身(它是web框架的资产绑定器的一部分),就无法解决此问题:在具有
shell=True
的Windows上,COMSPEC环境变量指定默认shell。您需要在Windows上指定
shell=True
的唯一时间是希望执行的命令内置到shell中时(例如dir或copy)。运行批处理文件或基于控制台的可执行文件不需要
shell=True
lessc
应该是1.3.3版,而
npm
是5年前我问这个问题时的1.2.18版。我目前没有一个Windows环境来测试这一点,所以从那时起可能有些变化?
>>> import subprocess
>>> subprocess.Popen([r'C:\Users\myname\AppData\Roaming\npm\lessc.cmd'])
<subprocess.Popen object at 0x035BA070>
>>> lessc: no input files

usage: lessc [option option=parameter ...] <source> [destination]
import plaform
import os

def where(file_name):
    # inspired by http://nedbatchelder.com/code/utilities/wh.py
    # see also: http://stackoverflow.com/questions/11210104/
    path_sep = ":" if platform.system() == "Linux" else ";"
    path_ext = [''] if platform.system() == "Linux" or '.' in file_name else os.environ["PATHEXT"].split(path_sep)
    for d in os.environ["PATH"].split(path_sep):
        for e in path_ext:
            file_path = os.path.join(d, file_name + e)
            if os.path.exists(file_path):
                return file_path
    raise Exception(file_name + " not found")
import subprocess
subprocess.Popen([where('lessc')])