2011-03-08 17 views
41

Potrzebuję skonfigurować środowisko, uruchamiając polecenie which abc. Czy istnieje odpowiednik w języku Python polecenia which? To jest mój kod."Która" równoważna funkcja w Pythonie

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

Nawet w samej powłoce, '' który' sam w sobie nie jest dobrym wyborem do wykrywania, czy polecenie jest zainstalowane. [Referencje] (http://stackoverflow.com/questions/592620/check-if-a-program-exists-od--bash-script/677212#677212) – kojiro

Odpowiedz

61
+5

+1, jest fajny i jest częścią standardowej biblioteki! Należy pamiętać, że jest bardzo ograniczony w systemie Windows - nie parsuje PATHEXT, zamiast tego zakłada, że ​​powinien szukać rozszerzenia ".exe" (brakujące pliki wsadowe itp.). – orip

+0

Działa doskonale, warto mieć swoje miejsce w wynikach Google. –

+2

Uwaga: nie sprawdza, czy plik jest wykonywalny. – temoto

11

Nie ma polecenie, aby to zrobić, ale można iteracyjne nad environ["PATH"] i patrzeć, czy plik istnieje, co jest rzeczywiście co which robi.

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 

Powodzenia!

+1

Chcesz zachować ostrożność, przyjmując założenia dotyczące postaci pathsep . –

+0

i separator ścieżek, ale jest to tylko dziwactwo, aby coś przekazać. Powodzenia! –

+0

użyj 'os.path.sep' zamiast'/'i' os.pathsep' zamiast ':' – djhaskin987

4

Można spróbować coś jak następuje:

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 
+0

Musisz wziąć również pod uwagę 'PATHEXT' – orip

+1

Na komputerze z systemem Windows podejrzewam, że prawdopodobnie będziesz szukał dokładnej nazwy pliku, zamiast zakładać rozszerzenia. W związku z tym nie byłoby trudno dodać wewnętrzną pętlę, która iteruje nad elementami PATHEXT. –

2

Jeśli używasz shell=True, wówczas polecenie będzie uruchamiane za pośrednictwem systemu powłoka, która automatycznie znajdzie plik binarny na ścieżce:

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

Nawet bez 'shell = True' jest wyszukiwany w ścieżce, ale nie pomaga, jeśli chcesz znaleźć, które z możliwych poleceń istnieje. –

22

Wiem, że jest to starsze pytanie, ale jeśli używasz Pythona w wersji 3.3 lub nowszej, możesz użyć shutil.which(cmd). Możesz znaleźć dokumentację here. Ma tę zaletę, że znajduje się w standardowej bibliotece.

Przykładem może być tak:

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

Jest to równoznaczne z którego polecenia, które nie tylko sprawdza, czy plik istnieje, ale także czy jest to plik wykonywalny:

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 
Powiązane problemy