실행 파일의 경로를 어떻게 찾을 수 있습니까?


84

바이너리 경로로 환경을 설정해야합니다. 셸 which에서 경로를 찾는 데 사용할 수 있습니다 . 파이썬에 상응하는 것이 있습니까? 이것은 내 코드입니다.

cmd = ["which","abc"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
res = p.stdout.readlines()
if len(res) == 0: return False
return True

셸 자체에서도 which명령이 설치되어 있는지 감지하는 데 적합하지 않습니다. 참조
kojiro

답변:


94

6
+1, 이것은 멋지고 표준 라이브러리의 일부입니다! Windows에서는 매우 제한적입니다. PATHEXT를 구문 분석하지 않고 대신 '.exe'확장자 (배치 파일 누락 등)를 검색해야한다고 가정합니다
orip

2
파일이 실행 가능한지 확인하지 않습니다.
temoto

1
2.7 또는 3.6에서는 작동하지 않았습니다. 스폰 모듈을 찾을 수 없다는 오류가 발생했습니다.
GreenMatt

@temoto 그럼에도 불구하고 Windows에서 나를 위해 dll 파일 (를 PATH통해 확인할 수 있음)을 찾지 못합니다 where.exe.
jpmc26

3.7에서 시도한 @GreenMatt는 잘 작동합니다. 다른 사람들이 언급했듯이 import distutils.spawn먼저 실행하는 것을 잊지 마십시오 .
zonksoft

82

나는 이것이 오래된 질문이라는 것을 알고 있지만 Python 3.3 이상을 사용하는 경우 shutil.which(cmd). 여기 에서 설명서를 찾을 수 있습니다 . 표준 라이브러리에 있다는 장점이 있습니다.

예는 다음과 같습니다.

>>> import shutil
>>> shutil.which("bash")
'/usr/bin/bash'

13

이를 수행하는 명령은 없지만 반복 environ["PATH"]해서 파일이 존재하는지 확인할 which수 있습니다. 실제로 수행하는 작업입니다.

import os

def which(file):
    for path in os.environ["PATH"].split(os.pathsep):
        if os.path.exists(os.path.join(path, file)):
                return os.path.join(path, file)

    return None

행운을 빕니다!


1
pathsep 캐릭터에 대해 신중하게 가정하고 싶습니다.
John Percival Hackworth 2011 년

그리고 경로 구분자이지만 이것은 요점을 만들기위한 기이 한 것입니다. 행운을 빕니다!
Gonzalo Larralde 2011 년

사용 os.path.sep대신 /하고 os.pathsep대신:
djhaskin987

2
'+'를 사용하지 말고 os.path.join을 사용하십시오. stdlib 구현 (distutils) 및 Twisted 프로젝트에서 플랫폼 독립적 인 것에 대한 더 많은 찬성 응답을 참조하십시오.
benjaoming jul.

os.path.join에 감사드립니다. 완전히 격리 된 트위스트 구현은 그렇게 구현으로는 (적어도 나보다) 훨씬 더, 프로젝트의 나머지 부분과 어떤 상호 의존성을 가지고하지 않는 것
곤잘로 Larralde


4

다음과 같은 것을 시도 할 수 있습니다.

import os
import os.path
def which(filename):
    """docstring for which"""
    locations = os.environ.get("PATH").split(os.pathsep)
    candidates = []
    for location in locations:
        candidate = os.path.join(location, filename)
        if os.path.isfile(candidate):
            candidates.append(candidate)
    return candidates

당신이 취할 필요 PATHEXT뿐만 아니라 고려
orip

2
Windows 시스템에서는 확장자를 가정하는 대신 파일의 정확한 이름을 찾을 가능성이 높습니다. 그렇게 말하면 PATHEXT의 구성원을 반복하는 내부 루프를 추가하는 것이 어렵지 않을 것입니다.
John Percival Hackworth 2011 년

3

을 사용하면 shell=True명령이 시스템 셸을 통해 실행되며 경로에서 바이너리를 자동으로 찾습니다.

p = subprocess.Popen("abc", stdout=subprocess.PIPE, shell=True)

심지어없이 shell=True그것은 경로에 조회됩니다,하지만 당신은 존재 가능한 명령하는 찾으려는 경우는 도움이되지 않습니다.
Antti Haapala 2015 년

3

이는 파일이 존재하는지뿐만 아니라 실행 가능한지 확인하는 which 명령과 동일합니다.

import os

def which(file_name):
    for path in os.environ["PATH"].split(os.pathsep):
        full_path = os.path.join(path, file_name)
        if os.path.exists(full_path) and os.access(full_path, os.X_OK):
            return full_path
    return None

0

다음은 이전 답변의 한 줄 버전입니다.

import os
which = lambda y: next(filter(lambda x: os.path.isfile(x) and os.access(x,os.X_OK),[x+os.path.sep+y for x in os.getenv("PATH").split(os.pathsep)]),None)

이렇게 사용 :

>>> which("ls")
'/bin/ls'

이것은 Python2에서 작동하지 않는 것 같습니다 TypeError: list object is not an iterator.
Gibbsoft
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.