복붙노트

[PYTHON] Python 스크립트의 프로그램이 있는지 확인하십시오.

PYTHON

Python 스크립트의 프로그램이 있는지 확인하십시오.

Python 스크립트의 프로그램이 있는지 어떻게 확인합니까?

wget이나 curl을 사용할 수 있는지 확인하려고한다고 가정 해 봅시다. 우리는 그들이 길에 있어야한다고 생각할 것입니다.

멀티 플랫폼 솔루션을 보는 것이 가장 좋겠지 만 지금은 Linux 만 있으면 충분합니다.

힌트 :

또한 is_tool (name)과 같이 좀 더 일반적인 해결책을 고맙게 생각합니다.

해결법

  1. ==============================

    1.나에게 아직 논의되지 않은 옵션을 추천하겠습니다 : Python 구현, 특히 shutil.which. Python 3.3에서 소개되었으며 Linux, Mac 및 Windows를 지원하는 교차 플랫폼입니다. whichcraft를 통해 Python 2.x에서도 사용할 수 있습니다. 또한 여기에서 어떤 코드를 뽑아서 프로그램에 삽입 할 수 있습니다.

    나에게 아직 논의되지 않은 옵션을 추천하겠습니다 : Python 구현, 특히 shutil.which. Python 3.3에서 소개되었으며 Linux, Mac 및 Windows를 지원하는 교차 플랫폼입니다. whichcraft를 통해 Python 2.x에서도 사용할 수 있습니다. 또한 여기에서 어떤 코드를 뽑아서 프로그램에 삽입 할 수 있습니다.

    def is_tool(name):
        """Check whether `name` is on PATH and marked as executable."""
    
        # from whichcraft import which
        from shutil import which
    
        return which(name) is not None
    

    이미 언급 된 또 다른 옵션은 distutils.spawn.find_executable입니다.

    find_executable의 docstring은 다음과 같습니다 :

    따라서주의를 기울이면 함수의 이름이 다소 오도 된 것임을 알 수 있습니다. find_executable은 실행 파일이 실행 파일로 표시되었는지 실제로 확인하지 않으며 PATH에 있음을 확인합니다. 따라서 find_executable은 프로그램이 사용 가능하지 않을 때 사용할 수 있다는 것을 전적으로 가능합니다 (그렇다고는보기 힘듭니다).

    예를 들어, 실행 가능으로 표시되지 않은 / usr / bin / wget 파일이 있다고 가정하십시오. 쉘에서 wget을 실행하면 다음 오류가 발생합니다. bash : / usr / bin / wget : 권한이 거부되었습니다. which ( 'wget') is not는 False를 반환하지만 find_executable ( 'wget')은 None이 아니므로 True를 반환합니다. 두 함수 중 하나를 사용하여 빠져 나갈 수는 있지만 find_executable을 사용하면 알 수 있습니다.

    def is_tool(name):
        """Check whether `name` is on PATH."""
    
        from distutils.spawn import find_executable
    
        return find_executable(name) is not None
    
  2. ==============================

    2.가장 쉬운 방법은 원하는 매개 변수를 사용하여 프로그램을 실행하고 존재하지 않는 경우 예외를 처리하는 것입니다.

    가장 쉬운 방법은 원하는 매개 변수를 사용하여 프로그램을 실행하고 존재하지 않는 경우 예외를 처리하는 것입니다.

    try:
        subprocess.call(["wget", "your", "parameters", "here"])
    except OSError as e:
        if e.errno == os.errno.ENOENT:
            # handle file not found error.
        else:
            # Something else went wrong while trying to run `wget`
            raise
    

    이것은 파이썬의 일반적인 패턴입니다 : EAFP

  3. ==============================

    3.다음과 함께 필요한 바이너리에 대한 서브 프로세스 호출을 사용할 수 있습니다.

    다음과 함께 필요한 바이너리에 대한 서브 프로세스 호출을 사용할 수 있습니다.

    실행 경로를 얻습니다 (환경 경로에 있다고 가정).

    import os 
    import platform
    import subprocess
    
    cmd = "where" if platform.system() == "Windows" else "which"
    try: 
        subprocess.call([cmd, your_executable_to_check_here])
    except: 
        print "No executable"
    

    또는 Ned Batchelder의 wh.py 스크립트를 사용하십시오. 이것은 "어떤"크로스 플랫폼 구현입니까?

    http://nedbatchelder.com/code/utilities/wh_py.html

  4. ==============================

    4.

    import subprocess
    import os
    
    def is_tool(name):
        try:
            devnull = open(os.devnull)
            subprocess.Popen([name], stdout=devnull, stderr=devnull).communicate()
        except OSError as e:
            if e.errno == os.errno.ENOENT:
                return False
        return True
    
  5. ==============================

    5.내가 갈거야 :

    내가 갈거야 :

    import distutils.spawn
    
    def is_tool(name):
      return distutils.spawn.find_executable(name) is not None
    
  6. ==============================

    6.나는 @ sorin의 대답을 다음과 같이 바꿀 것이다. 이유는 프로그램의 절대 경로를 지나치지 않고 프로그램의 이름을 검사하기 때문이다.

    나는 @ sorin의 대답을 다음과 같이 바꿀 것이다. 이유는 프로그램의 절대 경로를 지나치지 않고 프로그램의 이름을 검사하기 때문이다.

    from subprocess import Popen, PIPE
    
    def check_program_exists(name):
        p = Popen(['/usr/bin/which', name], stdout=PIPE, stderr=PIPE)
        p.communicate()
        return p.returncode == 0
    
  7. ==============================

    7.아마도 wget이나 curl을 사용하여 결과가 사용중인 프로그램의 이름으로 끝나는 지 확인하십시오. 유닉스의 마법 :)

    아마도 wget이나 curl을 사용하여 결과가 사용중인 프로그램의 이름으로 끝나는 지 확인하십시오. 유닉스의 마법 :)

    사실, 리턴 코드를 확인하기 만하면됩니다. 그래서 ... 우리의 신뢰할 수있는 서브 프로세스 모듈을 사용 :

    import subprocess
    
    rc = subprocess.call(['which', 'wget'])
    if rc == 0:
        print 'wget installed!'
    else:
        print 'wget missing in path!'
    

    Cygwin을 사용하여 창에서 이것을 테스트했음을 주목하십시오 ... 순수 파이썬에서 어떤 것을 구현하는지 알아 내고 싶다면 여기에서 확인하는 것이 좋습니다 : http://pypi.python.org/pypi/pycoreutils (oh dear-it 그들이 공급하지 않는 것 같다. 우호적 인 찌르다.

    업데이트 : Windows에서는 비슷한 효과 대신 어디에서 사용할 수 있습니다.

  8. ==============================

    8.

    import os
    import subprocess
    
    
    def is_tool(prog):
        for dir in os.environ['PATH'].split(os.pathsep):
            if os.path.exists(os.path.join(dir, prog)):
                try:
                    subprocess.call([os.path.join(dir, prog)],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
                except OSError, e:
                    return False
                return True
        return False
    
  9. ==============================

    9.@ SvenMarnach의 코드를 약간 수정하여 표준 출력 스트림에 인쇄하는 문제를 해결합니다. subprocess.call () 대신 subprocess.check_output () 함수를 사용하면 코드에서 표준 출력으로 인쇄되는 문자열을 처리 할 수 ​​있으며 예외 및 종료 상태 코드를 계속 catch 할 수 있습니다.

    @ SvenMarnach의 코드를 약간 수정하여 표준 출력 스트림에 인쇄하는 문제를 해결합니다. subprocess.call () 대신 subprocess.check_output () 함수를 사용하면 코드에서 표준 출력으로 인쇄되는 문자열을 처리 할 수 ​​있으며 예외 및 종료 상태 코드를 계속 catch 할 수 있습니다.

    터미널에서 표준 출력 스트림을 표시하지 않으려면 check_output에서 반환 된 표준 출력 문자열을 인쇄하지 마십시오.

    import subprocess
    import os
    try:
        stdout_string = subprocess.check_output(["wget", "--help"], stderr=subprocess.STDOUT)
        # print(stdout_string)
    except subprocess.CalledProcessError as cpe:
        print(cpe.returncode)
        print(cpe.output)
    except OSError as e:
        if e.errno == os.errno.ENOENT:
            print(e)
        else:
            # Something else went wrong while trying to run `wget`
            print(e)
    

    0이 아닌 종료 상태 코드와 출력 문자열은 CalledProcessError에서 subprocess.CalledProcessError.returncode 및 subprocess.CalledProcessError.output으로 발생하므로 사용자가 원하는 모든 작업을 수행 할 수 있습니다.

    실행 파일의 표준 출력을 터미널에 인쇄하려면 반환되는 문자열을 출력하십시오.

    import subprocess
    import os
    try:
        stdout_string = subprocess.check_output(["wget", "--help"], stderr=subprocess.STDOUT)
        print(stdout_string)
    except subprocess.CalledProcessError as cpe:
        print(cpe.returncode)
        print(cpe.output)
    except OSError as e:
        if e.errno == os.errno.ENOENT:
            print(e)
        else:
            # Something else went wrong while trying to run `wget`
            print(e)
    

    print ()는 추가 줄 바꿈을 문자열에 추가합니다. 그것을 없애고 (위의 print () 문과 같이 std out 스트림 대신 std err 스트림에 std 오류를 쓰려면) sys.stdout.write (string) 및 sys.stderr.write ) 대신 print () :

    import subprocess
    import os
    import sys
    try:
        stdout_string = subprocess.check_output(["bogus"], stderr=subprocess.STDOUT)
        sys.stdout.write(stdout_string)
    except subprocess.CalledProcessError as cpe:
        sys.stderr.write(cpe.returncode)
        sys.stderr.write(cpe.output)
    except OSError as e:
        if e.errno == os.errno.ENOENT:
            sys.stderr.write(e.strerror)
        else:
            # Something else went wrong while trying to run `wget`
            sys.stderr.write(e.strerror)
    
  10. ==============================

    10.데비안 기반 시스템 :

    데비안 기반 시스템 :

    나는 위의 스크립트를 테스트했는데별로 좋지 않았습니다. 그들은 프로그램을 실행하고 많은 시간이 걸리고 프로그램을 닫아야하기 때문에 성가신 일입니다. 설치된 패키지를 aptitude로 가져 와서 목록을 읽는 해결책을 찾았습니다.

    다른 종류의 명령을 사용하여 다른 종류의 '설치된 패키지'를 얻을 수 있습니다. 예 : https://askubuntu.com/questions/17823/how-to-list-all-installed-packages

    내가 가장 잘 찾은 두 가지는 :

    dpkg --get-selections           # big list
    aptitude search '~i!~M' -F      # great list
    

    터미널에서 실행하여 테스트 할 수 있습니다.

    파이썬 함수 :

    import os,sys
    
    def check_for_program(program):
    
        if not os.path.exists("/tmp/program_list"):
            os.system("aptitude search '~i!~M' -F > /tmp/program_list")
    
        with open('/tmp/program_list') as f:
            for line in f:
                if program in line:
                    return True
        return False
    
  11. from https://stackoverflow.com/questions/11210104/check-if-a-program-exists-from-a-python-script by cc-by-sa and MIT license