Windows subprocess.Popen a batch file without shell=True [英] Windows subprocess.Popen a batch file without shell=True
问题描述
我有一个运行 lessc
的函数(用 npm install -g less
安装):
不幸的是,除非我添加 shell=True
,否则它不起作用:
如何在不使用 shell=True
的情况下使 lessc
运行?
来自 https://docs.python.org/3/library/subprocess.html#subprocess.Popen 和 https://docs.python.org/2/library/subprocess.html#subprocess.Popen:
<块引用>您不需要 shell=True
来运行批处理文件或基于控制台的可执行文件.
那么,让我们试试:
lessc
实际告诉我们的地方
C:\Users\myname\AppData\Roaming\npm\lesscC:\Users\myname\AppData\Roaming\npm\lessc.cmd
也就是说,要执行的文件是lessc.cmd
,而不是一些.bat
文件.事实上:
因此,如果您指定完整路径,这确实有效.我认为当你有 这种体验时,有一个错字.可能你写的是 .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屋!