मैं एक निष्पादन योग्य के लिए रास्ता कैसे पा सकता हूं?


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

नहीं है distutils.spawn.find_executable()।


6
+1, यह शांत है और मानक पुस्तकालय का हिस्सा है! ध्यान रखें कि यह विंडोज पर बहुत सीमित है - यह पैथ पाठ को पार्स नहीं करता है, इसके बजाय यह मानता है कि इसे '.exe' एक्सटेंशन (बैच की फ़ाइलों को गायब करना) आदि के लिए खोज करना चाहिए
— orip

2
खबरदार यह जाँचें कि क्या फ़ाइल निष्पादन योग्य नहीं है।
— टेम्पो

1
यह मेरे लिए 2.7 या 3.6 पर काम नहीं किया। इसने एक त्रुटि दी कि स्पॉन मॉड्यूल नहीं मिला।
— ग्रीनमैट

@temoto और फिर भी के बावजूद है कि यह नहीं एक dll फ़ाइल (मैं जाँच कर सकते हैं कि पर है मिलेगा PATHके माध्यम से where.exe) मेरे लिए विंडोज पर।
— jpmc26

@GreenMatt, सिर्फ 3.7 पर कोशिश की, बस ठीक काम करता है। जैसा कि दूसरों ने उल्लेख किया है, import distutils.spawnपहले भागना मत भूलना ।
— zonksoft

82

मुझे पता है कि यह एक पुराना सवाल है, लेकिन अगर आप पायथन 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 चरित्र के बारे में सतर्क धारणा बनाना चाहते हैं।
— जॉन पेरिवल हैकवर्थ

और पथ विभाजक, लेकिन यह केवल एक बिंदु बनाने के लिए एक विचित्रता है। सौभाग्य!
— गोंजालो लाराल्डे

के os.path.sepबजाय /और के os.pathsepबजाय का उपयोग करें:
— djhaskin987

2
'+' का उपयोग न करें, os.path.join का उपयोग करें। Stdlib कार्यान्वयन (डिस्टुटिल्स) के लिए अधिक अप-वोट किए गए उत्तर और मुड़ प्रोजेक्ट से अधिक प्लेटफ़ॉर्म-स्वतंत्र देखें।
— बेंज

os.path.join के लिए धन्यवाद। मुड़ कार्यान्वयन पूरी तरह से अलग है, इस परियोजना के बाकी हिस्सों के साथ कोई अंतर-निर्भरता नहीं है, इसलिए कार्यान्वयन के रूप में यह बहुत बेहतर है (कम से कम मेरी तुलना में)
— गोंजालो लैराल्डे

13

( इसी तरह )

मुड़ कार्यान्वयन देखें: twisted.python.procutils.which


इसके साथ बात यह है कि इसे ट्विस्टेड मॉड्यूल को स्थापित करने की आवश्यकता है, जिसमें विंडोज (यहां तक ​​कि क्रिस्टोफ गोहले के पहियों के साथ) पर दर्दनाक होने की क्षमता है।
— आजी हैमरथिफ

1
मुड़ कार्यान्वयन का लिंक टूट गया है। ऐसा लगता है कि यहां पाया जा सकता है: github.com/twisted/twisted/blob/trunk/src/twisted/python/…
— rkersh

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
विंडोज मशीन पर मुझे संदेह है कि आप संभवतः एक्सटेंशन को मानने के विपरीत, फ़ाइल के सटीक नाम की तलाश करेंगे। इसके साथ ही कहा जा रहा है कि यह एक आंतरिक लूप जोड़ना मुश्किल नहीं होगा जो कि PATHEXT के सदस्यों पर निर्भर करता है।
— जॉन पेरिवल हैकवर्थ

3

यदि आप उपयोग करते हैं shell=True, तो आपका कमांड सिस्टम शेल के माध्यम से चलाया जाएगा, जो स्वचालित रूप से पथ पर बाइनरी को ढूंढेगा:

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

यहां तक ​​कि इसके बिना भी shell=Trueपथ में ऊपर देखा जाता है, लेकिन यह मदद नहीं करता है यदि आप यह खोजना चाहते हैं कि कौन से संभावित आदेश मौजूद हैं।
— अंती हापला

3

यह उस आदेश के समतुल्य है, जो न केवल जाँचता है कि फ़ाइल मौजूद है, बल्कि यह भी कि यह निष्पादन योग्य है:

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,।
— जिबसॉफ्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.