टेस्ट अगर निष्पादन योग्य पायथन में मौजूद है?


297

पायथन में, यदि निष्पादन योग्य कार्यक्रम मौजूद है, तो परीक्षण करने का एक पोर्टेबल और सरल तरीका है?

सरल से मेरा मतलब है कि whichकमांड जैसी कोई चीज जो एकदम सही होगी। मैं PATH को मैन्युअल रूप से या ऐसी किसी चीज़ से खोजना नहीं चाहता, जिसमें उसे Popen& al के साथ निष्पादित करने की कोशिश करना और यह देखना कि यह विफल है (कि अब मैं क्या कर रहा हूं, लेकिन कल्पना कीजिए launchmissiles)


4
पाथ पर्यावरण चर खोजने में क्या गलत है? आपको क्या लगता है UNIX 'जो' कमांड करता है?
Jay

1
क्या stdlib की कौन सी स्क्रिप्ट एक सरल तरीका है?
jfs

@JF - जो कि व्हाट्सएप स्क्रिप्ट incl है। पाइथन के साथ 'ls' पर निर्भर करता है और कुछ अन्य टिप्पणियों से संकेत मिलता है कि पियोट क्रॉस-प्लेटफ़ॉर्म उत्तर की तलाश में था।
Jay

@ जय: टिप्पणी के लिए धन्यवाद। मेरे पास विंडोज़ पर कोरुटिल्स स्थापित हैं, इसलिए मैंने यह नहीं देखा कि कौन सा थिंकपैड यूनिक्स-विशिष्ट है।
12

वहाँ भी है which:, तीसरे पक्ष के मॉड्यूल code.activestate.com/pypm/which
श्रीधर Ratnakumar

जवाबों:


321

सबसे आसान तरीका जो मैं सोच सकता हूं:

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

संपादित करें : केस को संभालने के लिए तर्क को शामिल करने के लिए अद्यतित कोड नमूना जहां प्रदान किया गया तर्क पहले से ही निष्पादन योग्य के लिए एक पूर्ण पथ है, जिसका अर्थ है "जो / बिन / लैंस"। यह UNIX के व्यवहार की नकल करता है, जो 'कमांड' है।

संपादित करें : प्रति टिप्पणियों में os.path.exist () के बजाय os.path.isfile () का उपयोग करने के लिए अद्यतन किया गया।

संपादित करें : path.strip('"')ऐसा लगता है कि यहाँ करना गलत है। उद्धृत आइटमों को प्रोत्साहित करने के लिए न तो Windows और न ही POSIX दिखाई देता है।


धन्यवाद जे, मैं आपका जवाब स्वीकार करता हूं, हालांकि मेरे लिए यह नकारात्मक द्वारा मेरे सवाल का जवाब देता है। इस तरह का कोई भी कार्य लिबास में मौजूद नहीं है, मुझे बस इसे लिखना है (मैं मानता हूं कि मेरा सूत्रीकरण इस तथ्य में पर्याप्त नहीं था कि मुझे पता है कि जो करता है)।
पियोट्र लेस्निकि

1
जय, यदि आप अपना उत्तर मेरे अनुसार पूरा करते हैं (पूरा 'w') तो मैं अपना निकाल सकता हूँ।
पायोत्र लेसनकी

2
कुछ OS के लिए आपको निष्पादन योग्य एक्सटेंशन जोड़ने की आवश्यकता हो सकती है। उदाहरण के लिए, उबंटू पर मैं लिख सकता हूं कि ("scp") लेकिन विंडोज पर, मुझे यह लिखने की जरूरत है कि कौन सा ("scp.exe")।
वफ़लमैन

13
मैं "os.path.exist" को "os.path.isfile" में बदलने का सुझाव दूंगा। अन्यथा यूनिक्स में यह गलत तरीके से + x बिट सेट के साथ एक निर्देशिका से मेल खा सकता है। मुझे इसे फ़ंक्शन के शीर्ष पर जोड़ने के लिए भी उपयोगी लगता है: आयात sys; अगर sys.platform == "win32" और न कि program.endswith ("exe"): + + = ".exe" प्रोग्राम। विंडोज के तहत इस तरह से आप या तो "कैल्क" या "कैल्सी। Exe" का उल्लेख कर सकते हैं, जैसे आप एक cmd विंडो में कर सकते हैं।
केविन इवरसेन

1
@KevinIvarsen एक बेहतर विकल्प होगा PATHEXTenv var के मूल्यों के माध्यम से पाशन करना क्योंकि यह बनाम के commandरूप command.comमें मान्य हैscriptscript.bat
Lekensteyn 8

325

मुझे पता है कि यह एक प्राचीन प्रश्न है, लेकिन आप इसका उपयोग कर सकते हैं distutils.spawn.find_executable। यह अजगर 2.4 के बाद से प्रलेखित किया गया है और अजगर 1.6 के बाद से अस्तित्व में है।

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

इसके अलावा, पायथन 3.3 अब प्रदान करता है shutil.which()


7
पर win32, distutils.spawn.find_executableकार्यान्वयन के लिए ही लग रहा है .exeबल्कि में सेट के लिए खोज करने के लिए एक्सटेंशन की सूची का उपयोग करने से %PATHEXT%। यह बहुत अच्छा नहीं है, लेकिन यह उन सभी मामलों के लिए काम कर सकता है जिनकी किसी को ज़रूरत है।
rakslice

7
उदाहरण उपयोग:from distutils import spawn php_path = spawn.find_executable("php")
कोडफ्री

6
जाहिरा तौर पर distutils.spawnमज़बूती से उपलब्ध नहीं है: OS X 10.10 पर पायथन 2.7.6 के मेरे सिस्टम इंस्टॉल (/ usr / bin / python) के साथ, मुझे मिलता है:, AttributeError: 'module' object has no attribute 'spawn'हालांकि अजीब तरह से यह पायनियर के समान संस्करण के साथ एक ही मशीन पर काम करता है, लेकिन एक virtualenv स्थापित करें।
जोश कुपरशमिड्ट 19

8
@JoshKupershmidt, सिंटैक्स import distutils.spawnका पालन करें या from distutils import spawnकेवल के बजाय सुनिश्चित करें import distutils। अन्यथा यह सुलभ नहीं हो सकता है और AttributeErrorयदि यह वहां है तो भी आपको ऊपर मिलेगा ।
जॉन सेंट जॉन


39

अजगर 3.2 और उससे पहले के लिए:

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

यह जे के उत्तर का एक-लाइनर है , यहाँ भी एक लंबोदर कवक के रूप में है:

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')

या अंत में, एक समारोह के रूप में प्रेरित:

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)
    )

अजगर 3.3 और बाद के लिए:

import shutil

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

जन-फिलिप गेर्क उत्तर के एक-लाइनर के रूप में :

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

एक हार के रूप में:

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

1
"एक फ़ंक्शन के रूप में इंडेंट" संस्करण चर का उपयोग करता है xजहां यह होना चाहिएcmd
0x89

आपको यह देखने के लिए एक परीक्षण जोड़ना होगा कि os.path.join(path, cmd)क्या फ़ाइल है, नहीं? आफ्टरआल, डाइरेक्टरीज़ में एक्ज़ीक्यूटेबल बिट सेट भी हो सकता है ...
MestreLion

@MestreLion जो एक संभावित मामले की तरह लगता है, क्या आप इस व्यवहार की पुष्टि करेंगे और इस उत्तर को अपडेट करेंगे? अगर यह मदद करता है तो मैं इस पोस्ट को एक समुदाय विकी में बदलकर खुश हूं।
थोरसुमोनर

1
@ थोरसुमोनर: मैंने इसकी पुष्टि की है, और यह वास्तव में फ़ाइल के लिए परीक्षण की आवश्यकता है। एक साधारण परीक्षण: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
मेस्त्रेलेयन

1
and os.path.isfile(...)उपयुक्त स्थानों पर एक साधारण जोड़ना पर्याप्त है कि
MestreLion

19

बस खिड़कियों पर फ़ाइल एक्सटेंशन निर्दिष्ट करना याद रखें। अन्यथा, आपको पर्यावरण चर is_exeका उपयोग करके विंडोज़ के लिए बहुत जटिल लिखना होगा PATHEXT। आप बस FindPath का उपयोग करना चाह सकते हैं

OTOH, तुम भी निष्पादन योग्य के लिए खोज करने के लिए क्यों परेशान कर रहे हैं? ऑपरेटिंग सिस्टम popenकॉल के हिस्से के रूप में आपके लिए यह करेगा और निष्पादन योग्य नहीं पाए जाने पर एक अपवाद को बढ़ाएगा। आपको बस इतना करना चाहिए कि दिए गए ओएस के लिए सही अपवाद को पकड़ना है। ध्यान दें कि विंडोज पर, subprocess.Popen(exe, shell=True)अगर exeनहीं मिला है तो चुपचाप विफल हो जाएगा ।


(जे के जवाब में) PATHEXTके उपरोक्त कार्यान्वयन में शामिल which:

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
इसने स्वीकार किए गए उत्तर में एक बग तय किया, महसूस करें कि यह उत्तर इसके बजाय शीर्ष पर होना चाहिए।
नीट लुओ

चतुर उपयोग के yieldमें ext_candidates, मुझे कैसे उस कीवर्ड काम करता है की एक बेहतर समझ दे दी है
अनुदान हम्फ्रीज़

15

* निक्स प्लेटफार्मों के लिए (लिनक्स और ओएस एक्स)

यह मेरे लिए काम कर रहा है:

Mestreion के लिए धन्यवाद, लिनक्स पर काम करने के लिए संपादित

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

हम यहां क्या कर रहे हैं बिलिन कमांड का उपयोग कर रहे हैं typeऔर निकास कोड की जांच कर रहे हैं । यदि ऐसा कोई आदेश नहीं है, typeतो 1 (या किसी भी तरह एक गैर-शून्य स्थिति कोड) से बाहर निकल जाएगा।

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

2
क्या आपको यकीन है कि यह काम करता है? यह एक बहुत अच्छा दृष्टिकोण है, लेकिन typeएक शेल बिल्डिन है, निष्पादन योग्य फ़ाइल नहीं है, इसलिए subprocess.call()यहां विफल रहता है।
MestreLion

1
क्या आपने इसे आज़माया है या आप सिर्फ सिद्धांत दे रहे हैं? यह वैसे भी मेरे मैक पर काम करता है।
hasen

मैंने इसे Ubuntu 12.04 में आज़माया है, यह फेंकता है OSError: [Errno 2] No such file or directory। शायद मैक typeमें एक वास्तविक आदेश है
मेस्टेरलियन

2
बहुत सारे परीक्षण के बाद , मैंने पाया है कि कैसे ठीक करना है: जोड़ने shell=Trueऔर बदलने के ["type", cmd]लिए"type " + cmd
MestreLion

4
ध्यान दें: सुनिश्चित करें कि चर "cmd" में मान्य डेटा है। यदि यह किसी बाहरी स्रोत से आता है, तो एक बुरा आदमी आपको "ls; rm -rf /" दे सकता है। मुझे लगता है कि इन-पायथन सॉल्यूशन (बिना उपप्रकार के) ज्यादा बेहतर है। अगला बिंदु: यदि आप इस पद्धति को अक्सर कहते हैं, तो सबप्रोसेस समाधान बहुत धीमा है, क्योंकि बहुत सारी प्रक्रियाओं की आवश्यकता होती है।
गुफ्तगू

7

Pathnames पर कुछ उपयोगी कार्यों के लिए os.path मॉड्यूल देखें । यह देखने के लिए कि क्या कोई मौजूदा फ़ाइल निष्पादन योग्य है, os.X_OK मोड के साथ os.access (पाथ, मोड) का उपयोग करें।

os.X_OK

मान का उपयोग करने के मोड पैरामीटर में शामिल करने के लिए (यह निर्धारित करने के लिए कि क्या पथ निष्पादित किया जा सकता है।

संपादित करें: सुझाए गए which()कार्यान्वयन os.path.join()पूर्ण फ़ाइल नाम बनाने के लिए उपयोग करते हुए एक सुराग याद कर रहे हैं ।


धन्यवाद, गिमेल, इसलिए मूल रूप से मेरा जवाब है: ऐसा कोई फ़ंक्शन मौजूद नहीं है, मुझे इसे मैन्युअल रूप से करना चाहिए।
पियोट्र लेस्निकि

Os.access का उपयोग न करें। एक्सेस फंक्शन suid प्रोग्राम के लिए बनाया गया है।
सूर्योदय

6

इस आधार पर कि अनुमति से क्षमा मांगना ज्यादा आसान है, मैं सिर्फ इसका उपयोग करने और त्रुटि को पकड़ने की कोशिश करूंगा (इस मामले में OSError - मैंने फ़ाइल की जाँच नहीं की है और फ़ाइल निष्पादन योग्य नहीं है और वे दोनों OSError देते हैं)।

यह मदद करता है अगर निष्पादन योग्य के पास --versionध्वज की तरह कुछ है जो एक त्वरित नो-ऑप है।

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

यह एक सामान्य समाधान नहीं है, लेकिन बहुत सारे उपयोग के मामलों के लिए सबसे आसान तरीका होगा - वे जहां कोड को एक एकल ज्ञात निष्पादन योग्य के लिए देखने की आवश्यकता है।


3
यह --versionएक कार्यक्रम के नाम पर कॉल करने के लिए भी खतरनाक है launchmissiles!
xApple

1
+1, मुझे यह तरीका पसंद है। ईएएफपी एक गोल्डन पायथन नियम है। यूआई स्थापित करने के लिए शायद छोड़कर, आप जानना चाहते हैं कि क्या launchmissiesमौजूद है जब तक आप मिसाइल लॉन्च नहीं करना चाहते हैं? इसे निष्पादित करने के लिए बेहतर है और बाहर निकलने की स्थिति / अपवादों पर कार्य करें
मेस्ट्रेलेन

इस पद्धति के साथ समस्या यह है कि आउटपुट कंसोल पर मुद्रित होता है। यदि आप पाइप और शेल = ट्रू का उपयोग करते हैं, तो OSError कभी नहीं उठती है
निक हमरिच

MacOS पर आपके पास उदाहरण के लिए स्टब एग्जीक्यूटिव भी होते हैं gitजो आप शायद आँख बंद करके नहीं चलाना चाहते हैं।
बॉब अमन

5

मुझे पता है कि मैं यहाँ एक नेक्रोमन्ट के लिए जा रहा हूँ, लेकिन मैं इस सवाल पर अड़ा रहा और स्वीकृत समाधान मेरे लिए सभी मामलों के लिए कारगर नहीं रहा, सोचा कि यह वैसे भी प्रस्तुत करने के लिए उपयोगी हो सकता है। विशेष रूप से, "निष्पादन योग्य" मोड का पता लगाने, और फ़ाइल एक्सटेंशन की आपूर्ति की आवश्यकता। इसके अलावा, दोनों python3.3 shutil.which(का उपयोग करता है PATHEXT) और python2.4 + का distutils.spawn.find_executable(सिर्फ जोड़ने की कोशिश करता है '.exe') केवल मामलों के एक सबसेट में काम करता है ।

इसलिए मैंने एक "सुपर" संस्करण लिखा (स्वीकृत उत्तर पर आधारित, और PATHEXTसूरज से सुझाव)। यह संस्करण 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, आदि भी निर्देशिका, जिनमें से एक (कोषगत पहले के बाद से शायद) के बजाय लौट रहे थे क्योंकि स्वीकार किए जाते हैं जवाब में निष्पादन परीक्षण अधूरा और दे रही थी में झूठी सकारात्मक।



2

मुझे StackOverflow में कुछ मिला जिसने मेरे लिए समस्या हल कर दी। यह काम करता है बशर्ते निष्पादन योग्य के पास एक विकल्प (जैसे --help या --version) है जो कुछ को आउटपुट करता है और शून्य से बाहर निकलने की स्थिति देता है। पायथन कॉल में दबाए गए आउटपुट को निष्पादनयोग्य के लिए देखें - कोड स्निपेट के अंत में "परिणाम" शून्य होगा यदि निष्पादन योग्य पथ में है, अन्यथा यह 1 होने की संभावना है।


2

यह काफी सरल लगता है और अजगर 2 और 3 दोनों में काम करता है

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

क्षमा करें, लेकिन यह समाधान केवल तभी काम करता है जब निष्पादन योग्य एक निकास कोड 1 को कॉल नहीं करता है अगर इसे गलत तरीके से कहा जाता है। इसलिए, उदाहरण के लिए, यह "dir" और "ls" के लिए काम करेगा, लेकिन यदि आप किसी ऐसी चीज़ के खिलाफ निष्पादित करते हैं जिसके लिए कॉन्फ़िगरेशन की आवश्यकता होती है, तो भी निष्पादन योग्य होने पर भी यह टूट जाएगा।
शपथ लें

1
"कॉन्फ़िगरेशन की आवश्यकता है" से आपका वास्तव में क्या मतलब है? अपने आप से 'जो' वास्तव में कुछ भी निष्पादित नहीं करता है, लेकिन सिर्फ इस नाम (आदमी जो) द्वारा एक निष्पादन योग्य के अस्तित्व के लिए पथ की जाँच करता है।
जाप

1
ओह, तो आप निष्पादन योग्य खोजने के लिए "जो" का उपयोग कर रहे हैं। तो यह केवल लिनक्स / यूनिक्स के लिए काम करता है?
स्प्रेड

1
उपयोग करना command -v executableया type executableसार्वभौमिक होना। ऐसे मामले हैं जो मैक पर अपेक्षित परिणाम नहीं देते हैं।
RJ

1

एक महत्वपूर्ण सवाल " निष्पादन योग्य होने पर आपको परीक्षण करने की आवश्यकता क्यों है?" शायद तुम नहीं? ;-)

हाल ही में मुझे PNG फ़ाइल के लिए दर्शक लॉन्च करने के लिए इस कार्यक्षमता की आवश्यकता थी। मैं कुछ पूर्वनिर्धारित दर्शकों पर पुनरावृति करना चाहता था और पहले मौजूद थे। सौभाग्य से, मैं भर आया os.startfile। यह ज़्यादा बेहतर है! सरल, पोर्टेबल और सिस्टम पर डिफ़ॉल्ट दर्शक का उपयोग करता है:

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

अपडेट: मैं os.startfileपोर्टेबल होने के बारे में गलत था ... यह केवल विंडोज है। Mac पर आपको openकमांड चलाना होगा । और xdg_openयूनिक्स पर। मैक और यूनिक्स समर्थन के लिए जोड़ने पर एक पायथन मुद्दा हैos.startfile



1

जोड़ा गया विंडोज़ समर्थन

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

आप बता सकते हैं कि ओएस मॉड्यूल के साथ कोई फाइल मौजूद है या नहीं। एक निष्पादन योग्य विशेष रूप से यह देखने के लिए बहुत सारी चीजों पर विचार करने योग्य नहीं है कि निक्स पर निष्पादन योग्य हैं जो खिड़कियों पर नहीं हैं और इसके विपरीत।


0

ऐसा प्रतीत होता है कि स्पष्ट विकल्प "वह" है, जो पॉपेन के माध्यम से परिणामों को पार्स कर रहा है, लेकिन आप इसे ओएस क्लास का उपयोग करके अन्यथा अनुकरण कर सकते हैं। छद्म रूप में, यह इस तरह दिखेगा:

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

मैं os.exec या कुछ इस तरह "कमांड" चलाने के बारे में सावधान रहूंगा। न केवल यह अक्सर धीमा होता है (यदि प्रदर्शन किसी प्रकार की चिंता है), लेकिन यदि आप अपने निष्पादन स्ट्रिंग के हिस्से के रूप में एक चर का उपयोग कर रहे हैं, तो सुरक्षा एक चिंता का विषय बन जाती है। कोई "rm -rf /" में चुपके कर सकता है।
परप्पा

1
जो, क्योंकि हम प्रोग्राम द्वारा बनाई गई कमांड को चलाने के लिए os.popen फ़ंक्शन का उपयोग कर रहे हैं, वास्तव में लागू नहीं होता है, नहीं?
चार्ली मार्टिन

2
धन्यवाद, लेकिन मुझे यकीन नहीं है कि अगर 'जो' खिड़कियों और पसंद पर मौजूद है। मैं अनिवार्य रूप से जानना चाहता था कि क्या कोई
फैब फेस्टिवल

मानक विंडोज इंस्टॉलेशन में, अभी भी कोई whichकमांड नहीं है ; एक UnxUtils संस्करण है, लेकिन आपको एक्सटेंशन को जानना / निर्दिष्ट करना होगा, अन्यथा प्रोग्राम नहीं मिलेगा।
टोबियास

0

तो मूल रूप से आप माउंटेड फाइलसिस्टम में एक फाइल ढूंढना चाहते हैं (जरूरी नहीं कि केवल पेटीएम डायरेक्टरी में ही) और जांचें कि क्या यह निष्पादन योग्य है। यह निम्नलिखित योजना का अनुवाद करता है:

  • स्थानीय रूप से माउंट किए गए फाइल सिस्टम में सभी फाइलों को गणना करें
  • नाम पैटर्न के साथ परिणाम मिलान
  • प्रत्येक फ़ाइल के लिए जाँच करें कि क्या यह निष्पादन योग्य है

मैं कहता हूँ, पोर्टेबल तरीके से ऐसा करने के लिए बहुत सारी कंप्यूटिंग शक्ति और समय की आवश्यकता होगी। क्या वास्तव में आपको इसकी आवश्यकता है?


0

मानक पायथन वितरण (जैसे विंडोज पर ) में एक व्हाट्सएप स्क्रिप्ट है '\PythonXX\Tools\Scripts\which.py'

EDIT: which.pyइस पर निर्भर करता है lsकि यह क्रॉस-प्लेटफ़ॉर्म नहीं है।


0

पिछले उदाहरणों में से कोई भी सभी प्लेटफार्मों पर काम नहीं करता है। आमतौर पर वे विंडोज पर काम करने में विफल होते हैं क्योंकि आप फ़ाइल एक्सटेंशन के बिना निष्पादित कर सकते हैं और यह कि आप नए एक्सटेंशन को पंजीकृत कर सकते हैं। उदाहरण के लिए विंडोज पर अगर अजगर अच्छी तरह से स्थापित है तो यह 'file.py' को निष्पादित करने के लिए पर्याप्त है और यह काम करेगा।

मेरे पास एकमात्र वैध और पोर्टेबल समाधान था कमांड को निष्पादित करना और त्रुटि कोड देखना। किसी भी सभ्य निष्पादन योग्य को कॉलिंग मापदंडों का एक सेट होना चाहिए जो कुछ भी नहीं करेगा।


-3

अजगर कपड़े पुस्तकालय का उपयोग:

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
यह बहुत बुरा सुझाव है। आप सचमुच एक स्थानीय कार्यक्रम (जो पायथन स्टडलिब आसानी से कर सकते हैं) को स्पॉन करने के लिए प्रोग्राम को दूरस्थ निष्पादन लाइब्रेरी पर निर्भर करते हैं, और इसके अलावा, आप इसके आधार पर हैं जो सभी प्रणालियों पर मौजूद नहीं है। which(1)
माइकल गोरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.