Kiểm tra nếu thực thi tồn tại trong Python?


297

Trong Python, có một cách di động và đơn giản để kiểm tra nếu một chương trình thực thi tồn tại?

Nói một cách đơn giản, ý tôi là thứ gì đó giống như whichlệnh sẽ hoàn hảo. Tôi không muốn tìm kiếm PATH một cách thủ công hoặc một cái gì đó liên quan đến việc cố gắng thực hiện nó với Popen& al và xem nếu nó thất bại (đó là những gì tôi đang làm bây giờ, nhưng hãy tưởng tượng nó launchmissiles)


4
Có gì sai khi tìm kiếm biến môi trường PATH? Bạn nghĩ lệnh UNIX 'which' làm gì?
Jay

1
Có phải script script nào từ stdlib là một cách đơn giản?
jfs

@JF - tập lệnh which.py ​​bao gồm. với Python phụ thuộc vào 'ls' và một số ý kiến ​​khác chỉ ra rằng Piotr đang tìm kiếm một câu trả lời đa nền tảng.
Jay

@Jay: Cảm ơn bạn đã bình luận. Tôi đã cài đặt coreutils trên Windows vì vậy tôi đã không nhận thấy rằng what.txt là không cụ thể.
jfs

Ngoài ra còn có whichmô-đun của bên thứ ba: code.activestate.com/pypm/which
Sridhar Ratnakumar

Câu trả lời:


321

Cách dễ nhất tôi có thể nghĩ ra:

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

Chỉnh sửa : Mẫu mã được cập nhật để bao gồm logic để xử lý trường hợp trong đó đối số được cung cấp đã là đường dẫn đầy đủ đến tệp thực thi, tức là "which / bin / ls". Điều này bắt chước hành vi của lệnh 'which' UNIX.

Chỉnh sửa : Đã cập nhật để sử dụng os.path.isfile () thay vì os.path.exists () cho mỗi bình luận.

Chỉnh sửa : path.strip('"')có vẻ như điều sai trái để làm ở đây. Cả Windows và POSIX đều không xuất hiện để khuyến khích các mục PATH được trích dẫn.


Cảm ơn Jay, tôi chấp nhận câu trả lời của bạn, mặc dù đối với tôi nó trả lời câu hỏi của tôi bằng cách phủ định. Không có chức năng như vậy tồn tại trong các lib, tôi chỉ phải viết nó (tôi thừa nhận công thức của tôi không đủ rõ ràng trong thực tế là tôi biết cái gì làm).
Piotr Lesnicki

1
Jay, nếu bạn hoàn thành câu trả lời của bạn theo tôi (để hoàn thành 'w') để tôi có thể xóa câu trả lời của tôi.
Piotr Lesnicki

2
Đối với một số HĐH, bạn có thể cần thêm tiện ích mở rộng của tệp thực thi. Ví dụ, trên Ubuntu tôi có thể viết cái nào ("scp") nhưng trên Windows, tôi cần phải viết cái nào ("scp.exe").
waffman

13
Tôi khuyên bạn nên thay đổi "os.path.exists" thành "os.path.isfile". Mặt khác, trong Unix, điều này có thể khớp với một thư mục với tập + x bit. Tôi cũng thấy hữu ích khi thêm phần này vào đầu hàm: import sys; if sys.pl platform == "win32" chứ không phải chương trình.endswith (". exe"): chương trình + = ".exe". Bằng cách này trong Windows, bạn có thể tham khảo "calc" hoặc "calc.exe", giống như bạn có thể làm trong cửa sổ cmd.
Kevin Ivarsen

1
@KevinIvarsen Một lựa chọn tốt hơn sẽ là vòng lặp thông qua các giá trị của PATHEXTvar env vì commandlà giá trị như command.comnhư là scriptvsscript.bat
Lekensteyn

325

Tôi biết đây là một câu hỏi cổ xưa, nhưng bạn có thể sử dụng distutils.spawn.find_executable. Điều này đã được ghi nhận từ python 2.4 và đã tồn tại từ python 1.6.

import distutils.spawn
distutils.spawn.find_executable("notepad.exe")

Ngoài ra, Python 3.3 hiện cung cấp shutil.which().


7
Bật win32, việc distutils.spawn.find_executabletriển khai chỉ tìm kiếm .exethay vì sử dụng danh sách các tiện ích mở rộng để tìm kiếm thiết lập %PATHEXT%. Điều đó không tuyệt vời, nhưng nó có thể hoạt động cho tất cả các trường hợp ai đó cần.
rakslice

7
sử dụng ví dụ:from distutils import spawn php_path = spawn.find_executable("php")
codefreak

6
Rõ ràng distutils.spawnlà không có sẵn một cách đáng tin cậy: với cài đặt Hệ thống của tôi (/ usr / bin / python) của Python 2.7.6 trên OS X 10.10, tôi nhận được AttributeError: 'module' object has no attribute 'spawn':, mặc dù thật lạ là nó hoạt động trên cùng một máy với cùng phiên bản Python, nhưng từ một cài đặt virtualenv.
Josh Kupershmidt

8
@JoshKupershmidt, đảm bảo import distutils.spawnhoặc theo from distutils import spawncú pháp chứ không chỉ import distutils. Nếu không, nó có thể không truy cập được và bạn sẽ nhận được ở trên AttributeErrorngay cả khi nó ở đó.
John St. John


39

Đối với python 3.2 trở về trước:

my_command = 'ls'
any(os.access(os.path.join(path, my_command), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))

Đây là một trong những câu trả lời của Jay , cũng ở đây với tư cách là một lambda func:

cmd_exists = lambda x: any(os.access(os.path.join(path, x), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))
cmd_exists('ls')

Hoặc cuối cùng, thụt lề như một chức năng:

def cmd_exists(cmd):
    return any(
        os.access(os.path.join(path, cmd), os.X_OK) 
        for path in os.environ["PATH"].split(os.pathsep)
    )

Đối với python 3.3 trở lên:

import shutil

command = 'ls'
shutil.which(command) is not None

Là một phần của Jan-Philip Gehrcke Trả lời :

cmd_exists = lambda x: shutil.which(x) is not None

Như một khuyết điểm:

def cmd_exists(cmd):
    return shutil.which(cmd) is not None

1
phiên bản "thụt lề như một chức năng" sử dụng biến số xcần cócmd
0x89

bạn cũng phải thêm một bài kiểm tra để xem nếu os.path.join(path, cmd)là một tập tin, phải không? Sau đó, các thư mục cũng có thể có tập bit thực thi ...
MestreLion

@MestreLion Nghe có vẻ giống như một trường hợp có thể xảy ra, bạn có phiền khi xác nhận hành vi này và cập nhật câu trả lời này không? Tôi rất vui khi thay đổi bài đăng này thành wiki cộng đồng nếu điều đó có ích.
ThorSummoner

1
@ThorSummoner: Tôi đã xác nhận nó và nó thực sự yêu cầu kiểm tra tệp. Một bài kiểm tra đơn giản:mkdir -p -- "$HOME"/bin/dummy && PATH="$PATH":"$HOME"/bin && python -c 'import os; print any(os.access(os.path.join(path, "dummy"), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))' && rmdir -- "$HOME"/bin/dummy
MestreLion

1
Thêm một đơn giản and os.path.isfile(...)vào những nơi thích hợp là đủ để khắc phục điều đó
MestreLion

19

Chỉ cần nhớ để xác định phần mở rộng tập tin trên windows. Mặt khác, bạn phải viết một phức tạp is_execho các cửa sổ bằng cách sử dụng PATHEXTbiến môi trường. Bạn có thể chỉ muốn sử dụng FindPath .

OTOH, tại sao bạn thậm chí còn bận tâm để tìm kiếm thực thi? Hệ điều hành sẽ thực hiện điều đó cho bạn như một phần của popencuộc gọi & sẽ đưa ra một ngoại lệ nếu không tìm thấy tệp thực thi. Tất cả những gì bạn cần làm là nắm bắt ngoại lệ chính xác cho HĐH đã cho. Lưu ý rằng trên Windows, subprocess.Popen(exe, shell=True)sẽ thất bại âm thầm nếu exekhông được tìm thấy.


Kết hợp PATHEXTvới việc thực hiện ở trên which(trong câu trả lời của 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

1
Nó đã sửa một lỗi trong câu trả lời được chấp nhận, thay vào đó hãy cảm nhận câu trả lời này.
NiTe Luo

sử dụng thông minh của yieldtrong ext_candidates, đã cho tôi hiểu rõ hơn về tác phẩm đó như thế nào từ khóa
Grant Humphries

15

Dành cho nền tảng * nix (Linux và OS X)

Điều này dường như đang làm việc cho tôi:

Được chỉnh sửa để hoạt động trên Linux, nhờ Mestreion

def cmd_exists(cmd):
    return subprocess.call("type " + cmd, shell=True, 
        stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0

Những gì chúng ta đang làm ở đây là sử dụng lệnh dựng sẵn typevà kiểm tra mã thoát. Nếu không có lệnh như vậy, typesẽ thoát bằng 1 (hoặc mã trạng thái khác không).

Một chút về thiết bị xuất chuẩn và thiết bị xuất chuẩn chỉ là để tắt đầu ra của typelệnh, vì chúng ta chỉ quan tâm đến mã trạng thái thoát.

Ví dụ sử dụng:

>>> cmd_exists("jsmin")
True
>>> cmd_exists("cssmin")
False
>>> cmd_exists("ls")
True
>>> cmd_exists("dir")
False
>>> cmd_exists("node")
True
>>> cmd_exists("steam")
False

2
Bạn có chắc chắn điều này hoạt động? Đó là một cách tiếp cận rất hay, nhưng typelà một shell dựng sẵn, không phải là tệp thực thi, nên đã subprocess.call()thất bại ở đây.
MestreLion

1
Bạn đã thử nó hay bạn chỉ là lý thuyết? Nó hoạt động trên máy Mac của tôi.
hasen

Tôi đã thử nó trong Ubuntu 12.04, nó ném OSError: [Errno 2] No such file or directory. Có lẽ trong Mac typelà một lệnh thực tế
MestreLion

2
Sau một LOT của thử nghiệm, tôi đã tìm thấy làm thế nào để sửa chữa: add shell=Truevà thay thế ["type", cmd]cho"type " + cmd
MestreLion

4
Chú ý: hãy chắc chắn rằng biến "cmd" chứa dữ liệu hợp lệ. Nếu nó đến từ một nguồn bên ngoài, một kẻ xấu có thể cung cấp cho bạn "ls; rm -rf /". Tôi nghĩ rằng giải pháp in-python (không có quy trình con) tốt hơn nhiều. Điểm tiếp theo: Nếu bạn gọi phương thức này thường xuyên, giải pháp quy trình con chậm hơn nhiều, vì rất nhiều quá trình cần phải sinh ra.
guettli

7

Xem mô-đun os.path để biết một số chức năng hữu ích trên tên đường dẫn. Để kiểm tra xem một tệp hiện có có thể thực thi được hay không, hãy sử dụng os.access (đường dẫn, chế độ) , với chế độ os.X_OK.

os.X_OK

Giá trị bao gồm trong tham số chế độ của access () để xác định xem đường dẫn có thể được thực thi hay không.

EDIT: Việc which()triển khai được đề xuất thiếu một đầu mối - sử dụng os.path.join()để xây dựng tên tệp đầy đủ.


Cảm ơn, gimel, vì vậy về cơ bản tôi có câu trả lời của mình: không có chức năng nào như vậy tồn tại, tôi phải thực hiện thủ công.
Piotr Lesnicki

Đừng sử dụng os.access. chức năng truy cập được thiết kế cho các chương trình suid.
Thay đổi CN

6

Trên cơ sở, việc xin tha thứ dễ dàng hơn sự cho phép, tôi chỉ cố gắng sử dụng và bắt lỗi (OSError trong trường hợp này - Tôi đã kiểm tra tệp không tồn tại và tệp không thể thực thi được và cả hai đều cho OSError).

Nó giúp nếu thực thi có một cái gì đó giống như một --versionlá cờ là một no-op nhanh chóng.

import subprocess
myexec = "python2.8"
try:
    subprocess.call([myexec, '--version']
except OSError:
    print "%s not found on path" % myexec

Đây không phải là một giải pháp chung, nhưng sẽ là cách dễ nhất cho nhiều trường hợp sử dụng - những trường hợp mã cần tìm một tệp thực thi nổi tiếng duy nhất.


3
Nó quá nguy hiểm ngay cả khi gọi --versionmột chương trình có tên launchmissiles!
xApple

1
+1, tôi thích cách tiếp cận này. EAFP là một quy tắc Python vàng. Ngoại trừ có lẽ để thiết lập UI, tại sao bạn muốn biết nếu launchmissiestồn tại trừ khi bạn muốn phóng tên lửa? Tốt hơn để thực hiện nó và hành động theo trạng thái thoát / ngoại lệ
MestreLion

Vấn đề với phương pháp này là đầu ra được in ra bàn điều khiển. Nếu bạn sử dụng ống và vỏ = Đúng, thì OSError không bao giờ được nâng lên
Nick Humrich

Trên macOS, bạn cũng có các tệp thực thi còn sơ khai, ví dụ như gitbạn có thể không muốn chạy một cách mù quáng.
Bob Aman

5

Tôi biết rằng tôi là một người cần thiết ở đây, nhưng tôi tình cờ thấy câu hỏi này và giải pháp được chấp nhận không phù hợp với tôi trong mọi trường hợp. Dù sao đi nữa, nó cũng có thể hữu ích. Cụ thể, phát hiện chế độ "thực thi" và yêu cầu cung cấp phần mở rộng tệp. Hơn nữa, cả python3.3 shutil.which(sử dụng PATHEXT) và python2.4 + distutils.spawn.find_executable(chỉ cố gắng thêm '.exe') chỉ hoạt động trong một tập hợp con của các trường hợp.

Vì vậy, tôi đã viết một phiên bản "siêu" (dựa trên câu trả lời được chấp nhận và PATHEXTgợi ý từ Suraj). Phiên bản whichnày thực hiện nhiệm vụ kỹ lưỡng hơn một chút và thử một loạt các kỹ thuật đầu tiên "broadphase", và cuối cùng thử các tìm kiếm chi tiết hơn trên PATHkhông gian:

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

Cách sử dụng trông như thế này:

>>> which.which("meld")
'C:\\Program Files (x86)\\Meld\\meld\\meld.exe'

Các giải pháp được chấp nhận không làm việc cho tôi trong trường hợp này, vì đã có các file thích meld.1, meld.ico, meld.doap, vv cũng trong thư mục, một trong số đó đã được trả lời thay vì (có lẽ kể từ thứ tự từ điển đầu tiên) vì kiểm tra thực thi trong câu trả lời được chấp nhận là không đầy đủ và đưa ra dương tính giả.



2

Tôi đã tìm thấy một cái gì đó trong StackOverflow đã giải quyết vấn đề cho tôi. Công việc này được cung cấp thực thi có một tùy chọn (như --help hoặc --version) để xuất ra một cái gì đó và trả về trạng thái thoát bằng không. Xem đầu ra Suppress trong các lệnh gọi Python tới các tệp thực thi - "kết quả" ở cuối đoạn mã trong câu trả lời này sẽ bằng 0 nếu tệp thực thi nằm trong đường dẫn, nếu không thì rất có thể là 1.


2

Điều này có vẻ đủ đơn giản và hoạt động cả trong python 2 và 3

try: subprocess.check_output('which executable',shell=True)
except: sys.exit('ERROR: executable not found')

Xin lỗi Jaap, nhưng giải pháp này chỉ hoạt động khi tệp thực thi không gọi mã thoát 1 nếu nó được gọi không chính xác. Vì vậy, ví dụ, nó sẽ hoạt động cho "dir" và "ls", nhưng nếu bạn thực thi đối với một cái gì đó yêu cầu cấu hình thì nó sẽ bị hỏng ngay cả khi thực thi ở đó.
Spedge

1
Bạn có ý nghĩa chính xác bởi "yêu cầu cấu hình" là gì? Chính nó 'mà' không thực sự thực thi bất cứ điều gì mà chỉ kiểm tra PATH về sự tồn tại của một thực thi bằng tên này (người đàn ông).
jaap

1
Ồ, vậy là bạn đang sử dụng "which" để tìm tệp thực thi. Vì vậy, điều này chỉ hoạt động cho Linux / Unix?
Spedge

1
Sử dụng command -v executablehoặc type executableđể được phổ quát. Có những trường hợp trên máy Mac không trả về kết quả mong đợi.
RJ

1

Một câu hỏi quan trọng là " Tại sao bạn cần kiểm tra nếu thực thi tồn tại?" Có lẽ bạn không? ;-)

Gần đây tôi cần chức năng này để khởi chạy trình xem cho tệp PNG. Tôi muốn lặp lại một số người xem được xác định trước và chạy cái đầu tiên tồn tại. May mắn thay, tôi đã đi qua os.startfile. Đó là điều tốt hơn nhiều! Đơn giản, di động và sử dụng trình xem mặc định trên hệ thống:

>>> os.startfile('yourfile.png')

Cập nhật: Tôi đã sai về os.startfileviệc di động ... Chỉ có Windows. Trên Mac bạn phải chạy openlệnh. Và xdg_opentrên Unix. Có một vấn đề Python về việc thêm hỗ trợ Mac và Unix cho os.startfile.



1

Đã thêm hỗ trợ windows

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

0

bạn có thể biết nếu một tập tin tồn tại với mô-đun os. một thực thi cụ thể có vẻ khá không thể xem xét khi xem xét rất nhiều thứ có thể thực thi được trên nix không có trên windows và ngược lại.


0

Có vẻ như sự lựa chọn rõ ràng là "cái", phân tích kết quả qua popen, nhưng bạn có thể mô phỏng nó bằng cách sử dụng lớp os. Trong pseudopython, nó sẽ trông như thế này:

for each element r in path:
    for each file f in directory p:
        if f is executable:
           return True

Tôi sẽ cẩn thận về việc chạy lệnh "which" bằng os.exec hoặc một cái gì đó tương tự. Nó không chỉ thường chậm (nếu hiệu suất là bất kỳ mối quan tâm nào), mà nếu bạn đang sử dụng một biến như một phần của chuỗi exec của mình, bảo mật sẽ trở thành mối quan tâm. Ai đó có thể lẻn vào "rm -rf /".
Parappa

1
Mà, vì chúng ta sẽ sử dụng hàm os.popen để chạy lệnh nào được tạo bởi chương trình, nên không thực sự áp dụng, phải không?
Charlie Martin

2
Cảm ơn, nhưng tôi không chắc liệu 'cái đó' có tồn tại trên windows và lượt thích hay không. Về cơ bản tôi muốn biết liệu có thứ gì đó lạ mắt tồn tại trong lib nổi bật hay không
Piotr Lesnicki

Trong các cài đặt Windows tiêu chuẩn, vẫn không có whichlệnh; có phiên bản UnxUtils, nhưng bạn phải biết / chỉ định tiện ích mở rộng, nếu không chương trình sẽ không được tìm thấy.
Tobias

0

Vì vậy, về cơ bản, bạn muốn tìm một tệp trong hệ thống tệp được gắn (không nhất thiết chỉ trong các thư mục PATH) và kiểm tra xem nó có thể thực thi được không. Điều này có nghĩa là kế hoạch sau đây:

  • liệt kê tất cả các tệp trong hệ thống tệp được gắn cục bộ
  • kết quả khớp với mẫu tên
  • cho mỗi tập tin tìm thấy kiểm tra nếu nó là thực thi

Tôi muốn nói, làm điều này theo cách di động sẽ đòi hỏi nhiều sức mạnh và thời gian tính toán. Có thực sự là những gì bạn cần?


0

Có một tập lệnh which.txt trong bản phân phối Python chuẩn (ví dụ: trên Windows'\PythonXX\Tools\Scripts\which.py' ).

EDIT: which.pyphụ thuộc vào lsdo đó nó không phải là đa nền tảng.


0

Không có ví dụ nào trước đây hoạt động trên tất cả các nền tảng. Thông thường, chúng không hoạt động trên Windows vì bạn có thể thực thi mà không có phần mở rộng tệp bạn có thể đăng ký tiện ích mở rộng mới. Ví dụ: trên Windows nếu python được cài đặt tốt, nó đủ để thực thi 'file.py' và nó sẽ hoạt động.

Giải pháp hợp lệ và di động duy nhất tôi có là thực thi lệnh và xem mã lỗi. Bất kỳ thực thi tốt nên có một bộ các tham số gọi sẽ không làm gì.


-3

Sử dụng thư viện vải python:

from fabric.api import *

def test_cli_exists():
    """
    Make sure executable exists on the system path.
    """
    with settings(warn_only=True):
        which = local('which command', capture=True)

    if not which:
        print "command does not exist"

    assert which

2
Đây là một đề nghị rất xấu . Bạn thực sự làm cho chương trình phụ thuộc vào thư viện thực thi từ xa để sinh ra một chương trình cục bộ (mà Python stdlib có thể thực hiện dễ dàng), và ngoài ra, bạn phụ thuộc vào which(1)chương trình không có trên tất cả các hệ thống.
Michał Górny
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.