<질문>
Python에서 실행 가능한 프로그램이 있는지 테스트하는 이식 가능하고 간단한 방법이 있습니까?
간단히 말해서 나는which
완벽한 명령입니다. PATH를 수동으로 검색하거나 실행하려는 것과 관련된 것을 원하지 않습니다.Popen
& al 그리고 그것이 실패하는지 확인하십시오 (그게 내가 지금하고있는 일이지만, 그것이launchmissiles
)
<답변1>
내가 생각할 수있는 가장 쉬운 방법 :
def which(program):
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
return None
편집하다: 제공된 인수가 이미 실행 파일의 전체 경로 (예 : "which / bin / ls") 인 경우 처리 논리를 포함하도록 코드 샘플을 업데이트했습니다. 이것은 UNIX 'which'명령의 동작을 모방합니다.
편집하다: 주석마다 os.path.exists () 대신 os.path.isfile ()을 사용하도록 업데이트되었습니다.
편집하다:path.strip('"')
여기서하는 것은 잘못된 것 같습니다. Windows와 POSIX 모두 인용 된 PATH 항목을 권장하지 않습니다.
<답변2>
나는 이것이 고대의 질문이라는 것을 알고 있지만distutils.spawn.find_executable
. 이것은documented since python 2.4그리고 파이썬 1.6 이후 존재했습니다.
import distutils.spawn
distutils.spawn.find_executable("notepad.exe")
또한 Python 3.3은 이제shutil.which()
.
<답변3>
사용하다shutil.which()Python의 멋진 표준 라이브러리에서. 배터리 포함!
<답변4>
import shutil
command = 'ls'
shutil.which(command) is not None
한 줄로Jan-Philip Gehrcke Answer:
cmd_exists = lambda x: shutil.which(x) is not None
정의로 :
def cmd_exists(cmd):
return shutil.which(cmd) is not None
my_command = 'ls'
any(
(
os.access(os.path.join(path, my_command), os.X_OK)
and os.path.isfile(os.path.join(path, my_command)
)
for path in os.environ["PATH"].split(os.pathsep)
)
이것은 한 줄의Jay's Answer, 또한 여기 람다 함수로 :
cmd_exists = lambda x: any((os.access(os.path.join(path, x), os.X_OK) and os.path.isfile(os.path.join(path, x))) for path in os.environ["PATH"].split(os.pathsep))
cmd_exists('ls')
또는 마지막으로 함수로 들여 쓰기 :
def cmd_exists(cmd, path=None):
""" test if path contains an executable file with name
"""
if path is None:
path = os.environ["PATH"].split(os.pathsep)
for prefix in path:
filename = os.path.join(prefix, cmd)
executable = os.access(filename, os.X_OK)
is_not_directory = os.path.isfile(filename)
if executable and is_not_directory:
return True
return False
<답변5>
Windows에서 파일 확장자를 지정하는 것을 잊지 마십시오. 그렇지 않으면 훨씬 복잡한is_exe
Windows 용PATHEXT
환경 변수. 그냥 사용하고 싶을 수도 있습니다.FindPath.
OTOH, 실행 파일을 검색하는 데 왜 귀찮게합니까? 운영 체제는 다음의 일부로이를 수행합니다.popen
실행 파일을 찾을 수없는 경우 & 호출은 예외를 발생시킵니다. 주어진 OS에 대한 올바른 예외를 포착하기 만하면됩니다. Windows에서는subprocess.Popen(exe, shell=True)
다음과 같은 경우 조용히 실패합니다exe
찾을 수 없습니다.
통합PATHEXT
위의 구현에which
(Jay의 답변에서) :
def which(program):
def is_exe(fpath):
return os.path.exists(fpath) and os.access(fpath, os.X_OK) and os.path.isfile(fpath)
def ext_candidates(fpath):
yield fpath
for ext in os.environ.get("PATHEXT", "").split(os.pathsep):
yield fpath + ext
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
for candidate in ext_candidates(exe_file):
if is_exe(candidate):
return candidate
return None
<답변6>
이것은 나를 위해 일하는 것 같습니다.
수정 됨덕분에 Linux에서 작업Mestreion
def cmd_exists(cmd):
return subprocess.call("type " + cmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0
여기서 우리가하는 것은 내장 명령을 사용하는 것입니다.type
종료 코드를 확인합니다. 그런 명령이 없다면type
1 (또는 어쨌든 0이 아닌 상태 코드)으로 종료됩니다.
stdout 및 stderr에 대한 내용은type
명령, 우리는 종료 상태 코드에만 관심이 있기 때문입니다.
사용 예 :
>>> cmd_exists("jsmin")
True
>>> cmd_exists("cssmin")
False
>>> cmd_exists("ls")
True
>>> cmd_exists("dir")
False
>>> cmd_exists("node")
True
>>> cmd_exists("steam")
False
<답변7>
보다os.path경로 이름에 대한 몇 가지 유용한 기능에 대한 모듈. 기존 파일이 실행 가능한지 확인하려면os.access(path, mode), os.X_OK 모드.
os.X_OK 경로를 실행할 수 있는지 결정하기 위해 access ()의 모드 매개 변수에 포함 할 값입니다.
편집하다:제안which()
구현에는 단서 하나가 누락되었습니다.os.path.join()
전체 파일 이름을 빌드합니다.
<답변8>
나는 내가 여기서 약간 네크로맨서라는 것을 알고 있지만, 나는이 질문을 우연히 발견했고 받아 들여진 해결책이 모든 경우에 작동하지 않았다. 어쨌든 제출하는 것이 유용 할 것이라고 생각했다. 특히 "실행 가능"모드 감지 및 파일 확장자 제공 요구 사항. 또한 python3.3 모두shutil.which
(사용PATHEXT
) 및 python2.4 +distutils.spawn.find_executable
(그냥 추가하려고'.exe'
) 일부 케이스에서만 작동합니다.
그래서 저는 "수퍼"버전을 작성했습니다 (수용된 답변을 바탕으로PATHEXT
Suraj의 제안). 이 버전의which
작업을 좀 더 철저히 수행하고 먼저 일련의 "광범위한"폭 우선 기법을 시도한 다음 결국에는 더 세분화 된 검색을 시도합니다.PATH
우주:
import os
import sys
import stat
import tempfile
def is_case_sensitive_filesystem():
tmphandle, tmppath = tempfile.mkstemp()
is_insensitive = os.path.exists(tmppath.upper())
os.close(tmphandle)
os.remove(tmppath)
return not is_insensitive
_IS_CASE_SENSITIVE_FILESYSTEM = is_case_sensitive_filesystem()
def which(program, case_sensitive=_IS_CASE_SENSITIVE_FILESYSTEM):
""" Simulates unix `which` command. Returns absolute path if program found """
def is_exe(fpath):
""" Return true if fpath is a file we have access to that is executable """
accessmode = os.F_OK | os.X_OK
if os.path.exists(fpath) and os.access(fpath, accessmode) and not os.path.isdir(fpath):
filemode = os.stat(fpath).st_mode
ret = bool(filemode & stat.S_IXUSR or filemode & stat.S_IXGRP or filemode & stat.S_IXOTH)
return ret
def list_file_exts(directory, search_filename=None, ignore_case=True):
""" Return list of (filename, extension) tuples which match the search_filename"""
if ignore_case:
search_filename = search_filename.lower()
for root, dirs, files in os.walk(path):
for f in files:
filename, extension = os.path.splitext(f)
if ignore_case:
filename = filename.lower()
if not search_filename or filename == search_filename:
yield (filename, extension)
break
fpath, fname = os.path.split(program)
# is a path: try direct program path
if fpath:
if is_exe(program):
return program
elif "win" in sys.platform:
# isnt a path: try fname in current directory on windows
if is_exe(fname):
return program
paths = [path.strip('"') for path in os.environ.get("PATH", "").split(os.pathsep)]
exe_exts = [ext for ext in os.environ.get("PATHEXT", "").split(os.pathsep)]
if not case_sensitive:
exe_exts = map(str.lower, exe_exts)
# try append program path per directory
for path in paths:
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
# try with known executable extensions per program path per directory
for path in paths:
filepath = os.path.join(path, program)
for extension in exe_exts:
exe_file = filepath+extension
if is_exe(exe_file):
return exe_file
# try search program name with "soft" extension search
if len(os.path.splitext(fname)[1]) == 0:
for path in paths:
file_exts = list_file_exts(path, fname, not case_sensitive)
for file_ext in file_exts:
filename = "".join(file_ext)
exe_file = os.path.join(path, filename)
if is_exe(exe_file):
return exe_file
return None
사용법은 다음과 같습니다.
>>> which.which("meld")
'C:\\Program Files (x86)\\Meld\\meld\\meld.exe'
이 경우에는 다음과 같은 파일이 있었기 때문에 허용 된 솔루션이 작동하지 않았습니다.meld.1
,meld.ico
,meld.doap
, 등도 디렉토리에 있는데, 그 중 하나가 대신 반환되었습니다 (아마도 사전에 처음부터) 허용 된 답변의 실행 가능한 테스트가 불완전하고 오탐을 제공했기 때문입니다.
<답변9>
그것을 기초로easier to ask forgiveness than permission(중요하게는 명령을 실행하는 것이 안전하다는 것입니다) 그냥 사용하려고 시도하고 오류를 잡았습니다 (이 경우 OSError-파일이 존재하지 않고 파일이 실행 가능하지 않은지 확인하고 둘 다 OSError를 제공합니다).
실행 파일에 다음과 같은 것이 있으면 도움이됩니다.--version
신속하게 작동하지 않는 플래그입니다.
import subprocess
myexec = "python2.8"
try:
subprocess.call([myexec, '--version']
except OSError:
print "%s not found on path" % myexec
이것은 일반적인 해결책은 아니지만 많은 사용 사례에서 가장 쉬운 방법이 될 것입니다. 코드가 실행하기에 안전하거나 적어도 주어진 플래그로 실행하기에 안전한 단일 잘 알려진 실행 파일을 찾아야하는 경우입니다.
<답변10>
윈도우 지원 추가
def which(program):
path_ext = [""];
ext_list = None
if sys.platform == "win32":
ext_list = [ext.lower() for ext in os.environ["PATHEXT"].split(";")]
def is_exe(fpath):
exe = os.path.isfile(fpath) and os.access(fpath, os.X_OK)
# search for executable under windows
if not exe:
if ext_list:
for ext in ext_list:
exe_path = "%s%s" % (fpath,ext)
if os.path.isfile(exe_path) and os.access(exe_path, os.X_OK):
path_ext[0] = ext
return True
return False
return exe
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return "%s%s" % (program, path_ext[0])
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return "%s%s" % (exe_file, path_ext[0])
return None
<답변11>
중요한 질문은 "왜실행 파일이 있는지 테스트해야합니까? "그렇지 않을 수도 있습니다. ;-)
최근에 PNG 파일 용 뷰어를 시작하려면이 기능이 필요했습니다. 미리 정의 된 일부 뷰어를 반복하고 존재하는 첫 번째 뷰어를 실행하고 싶었습니다. 다행히도os.startfile
. 훨씬 좋습니다! 간단하고 휴대 가능하며기본시스템의 뷰어 :
>>> os.startfile('yourfile.png')
최신 정보:내가 틀렸다os.startfile
휴대 가능 ... Windows 전용입니다. Mac에서는 실행해야합니다open
명령. 과xdg_open
유닉스에서. 거기에Python issueMac 및 Unix 지원 추가os.startfile
.
<답변12>
이것은 충분히 간단 해 보이며 파이썬 2와 3 모두에서 작동합니다.
try: subprocess.check_output('which executable',shell=True)
except: sys.exit('ERROR: executable not found')
<답변13>
"sh"라는 외부 라이브러리를 사용해 볼 수 있습니다 (http://amoffat.github.io/sh/).
import sh
print sh.which('ls') # prints '/bin/ls' depending on your setup
print sh.which('xxx') # prints None
<답변14>
따라서 기본적으로 마운트 된 파일 시스템 (PATH 디렉터리에만있는 것은 아님)에서 파일을 찾고 실행 가능한지 확인하려고합니다. 이는 다음 계획으로 변환됩니다.
- 로컬로 마운트 된 파일 시스템의 모든 파일을 열거합니다.
- 이름 패턴으로 결과 일치
- 발견 된 각 파일에 대해 실행 가능한지 확인하십시오.
휴대용 방식으로이 작업을 수행하려면 많은 컴퓨팅 성능과 시간이 필요합니다. 정말 필요한 건가요?
<답변15>
이있다which.py표준 Python 배포의 스크립트 (예 : Windows'\PythonXX\Tools\Scripts\which.py'
).
편집하다:which.py
에 달려있다ls
따라서 크로스 플랫폼이 아닙니다.
'개발 > Python' 카테고리의 다른 글
Python에서 빈 리스트 만들기 (0) | 2021.01.07 |
---|---|
파이썬에서 데몬을 어떻게 생성합니까? (0) | 2021.01.07 |
UnicodeDecodeError : 'utf8'코덱이 바이트 0x9c를 디코딩 할 수 없습니다. (0) | 2021.01.07 |
Python에서 쿼리 문자열을 urlencode하는 방법은 무엇입니까? (0) | 2021.01.07 |