Windows subprocess.Popen a batch file without shell=True [英] Windows subprocess.Popen a batch file without shell=True

查看:32
本文介绍了Windows subprocess.Popen a batch file without shell=True的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<预><代码>>>>导入子流程>>>subprocess.Popen(['lessc'])回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中文件C:\Python27\lib\subprocess.py",第 679 行,在 __init__ 中错误读取,错误写入)文件C:\Python27\lib\subprocess.py",第 896 行,在 _execute_child启动信息)WindowsError: [错误 2] 系统找不到指定的文件

不幸的是,除非我添加 shell=True,否则它不起作用:

<预><代码>>>>subprocess.Popen(['lessc'], shell=True)<subprocess.Popen 对象在 0x01F619D0>

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

解决方案

来自 https://docs.python.org/3/library/subprocess.html#subprocess.Popenhttps://docs.python.org/2/library/subprocess.html#subprocess.Popen:

<块引用>

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

已经@JBernardo 引用.

那么,让我们试试:

lessc 实际告诉我们的地方

C:\Users\myname\AppData\Roaming\npm\lesscC:\Users\myname\AppData\Roaming\npm\lessc.cmd

也就是说,要执行的文件是lessc.cmd,而不是一些.bat 文件.事实上:

<预><代码>>>>导入子流程>>>subprocess.Popen([r'C:\Users\myname\AppData\Roaming\npm\lessc.cmd'])<subprocess.Popen 对象在 0x035BA070>>>>lessc:没有输入文件用法:lessc [option option=parameter ...] <source>[目的地]

因此,如果您指定完整路径,这确实有效.我认为当你有 这种体验时,有一个错字.可能你写的是 .bat 而不是 .cmd?

<小时>

如果你不想把lessc的完整路径打到你的脚本中,你可以自己烘焙一个where:

导入平台导入操作系统定义在哪里(文件名):# 灵感来自 http://nedbatchelder.com/code/utilities/wh.py# 另见:http://stackoverflow.com/questions/11210104/path_sep = ":" if platform.system() == "Linux" else ";"path_ext = [''] 如果 platform.system() == "Linux" 或 '.'在 file_name else os.environ["PATHEXT"].split(path_sep)对于 os.environ["PATH"].split(path_sep) 中的 d:对于路径_ext 中的 e:file_path = os.path.join(d, file_name + e)如果 os.path.exists(file_path):返回文件路径引发异常(文件名+未找到")

然后你可以写:

导入子流程subprocess.Popen([where('lessc')])

I have a function that runs lessc (installed with npm install -g less):

>>> import subprocess
>>> subprocess.Popen(['lessc'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

Unfortunately, it doesn't work unless I add shell=True:

>>> subprocess.Popen(['lessc'], shell=True)
<subprocess.Popen object at 0x01F619D0>

What can I do to make lessc run without using shell=True?

解决方案

From both https://docs.python.org/3/library/subprocess.html#subprocess.Popen and https://docs.python.org/2/library/subprocess.html#subprocess.Popen:

You do not need shell=True to run a batch file or console-based executable.

as already cited by @JBernardo.

So, lets try:

where lessc actually tells

C:\Users\myname\AppData\Roaming\npm\lessc
C:\Users\myname\AppData\Roaming\npm\lessc.cmd

That means, the file to execute is lessc.cmd, not some .bat file. And indeed:

>>> 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]

So, this does work if you specify the full path. I assume there was a typo involved when you had this experience. May be you wrote .bat instead of .cmd?


If you don't want to patch the full path of lessc into your script, you can bake yourself a where:

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")

Then you can write:

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

这篇关于Windows subprocess.Popen a batch file without shell=True的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆