我正在尝试编写一个独立于平台的Python (>=3.6.5)包,其中包含一些需要使用javac编译和使用java运行的java .class文件。这是一个很简单的任务,但我需要知道用户是否已经安装了这些文件,以及假设它们都不在系统路径上的可执行文件的位置。这样,我就可以使用subprocess.run通过它的路径调用可执行文件。这给我带来了一个与平台无关的whereis命令。
import os, subprocess
from subprocess import CalledProcessError
def whereis(app):
"""Return a list of locations a given application.
Relies on the `where` system command in Windows and the `whereis` command in Unix.
Parameters
----------
app : str
Can be any application on the system path e.g. java.
Returns
-------
result : list
A list of locations where applications is installed.
Useage
------
>>>whereis('javac')
'C:\\Program Files\\Java\\jdk1.8.0_162\\bin\\javac.exe'
"""
result = None
if os.name == "nt":# Windows
try:
result = subprocess.check_output("where {}".format(app))
except CalledProcessError as err:
print("Application ,",app,", not forund.",err)
else:# Unix
try:
result = subprocess.check_output("whereis {}".format(app))
except CalledProcessError as err:
print("Application ,",app,", not found.",err)
if result is None:
print("")
result = []
return result
else:
result = result.decode().replace("\r", "").split("\n")
result = list(filter(lambda x: len(x)>0, result))
return result发布于 2018-03-30 22:06:27
小nit:
# Split this into individual lines - much easier to read
import os, subprocess减少重复的代码和嵌套(同时也使用which) --这对于它所需要的内容来说太复杂了(我没有测试它):
def whereis(app):
result = None
command = 'where'
if os.name != "nt":# Windows
command = 'which'
try:
result = subprocess.check_output("{} {}".format(command, app))
except CalledProcessError as err:
print("Application ,",app,", not found.",err)
if result is None:
return []
result = result.decode().splitlines()
return [line for line in result if len(line)]发布于 2018-03-31 23:10:08
您可以使用一个三值条件运算符来确定每个操作系统的命令,使这个逻辑位为一个一行。除非对您的预期使用是必要的,否则我不认为返回空列表的意义,只要返回None,如果您的脚本什么也找不到。如果您在其他地方有一些代码看起来很像:
if not paths:
# do something如果paths是一个空列表,那么如果我们将它更改为None,它的工作方式将完全相同。
import os
import subprocess
def whereis(app):
command = 'which' if os.name != 'nt' else 'where'
try:
result = subprocess.check_output('{} {}'.format(command, app), stderr=subprocess.STDOUT)
return result.decode().split()
except subprocess.CalledProcessError:
return
if __name__ == '__main__':
paths = whereis('notepad')输出:
['C:\\Windows\\System32\\notepad.exe', 'C:\\Windows\\notepad.exe']发布于 2019-03-02 11:57:33
据我所知,您的代码对于空格或shell字符都是零转义,因此我假设它非常不安全,可以很容易地用于接管/ crash /.传递恶意输入时的整个应用程序。
您确实需要使用shlex.quote或类似的东西,或者使用which作为内置的非bash:subprocess.check_output(["which", your_argument])。
https://codereview.stackexchange.com/questions/190886
复制相似问题