2010-05-03 14 views
22

Devo ottenere il nome di distribuzione di Linux da uno script Python. C'è un metodo dist nel modulo della piattaforma:Controllare il nome di distribuzione di Linux

import platform 
platform.dist() 

Ma sotto la mia Arch Linux restituisce:

>>> platform.dist() 
('', '', '') 

Perché? Come posso ottenere il nome?

PS. Devo controllare se la distribuzione è basata su Debian.


Aggiornamento: Ho trovato qui Python site, che dist() è sconsigliata dal 2.6.

>>> platform.linux_distribution() 
('', '', '') 
+0

@Kimvais Voglio dire ottenere il nome esattamente dallo script python senza analizzare alcun file, solo metodi standard. – Ockonal

+0

cosa restituisce 'uname -a' su Arch? platform.py è 1600 linee di prova di tutto ciò a cui possono pensare per distinguere i vari sistemi; è un enorme mucchio di euristiche. Anche Arch sembra basarsi solo su se stesso, nessun'altra distro: http://en.wikipedia.org/wiki/Arch_Linux – msw

+0

Cosa restituisce "lsb_release" in Arch? Se 'platform.dist()' non fornisce dati utilizzabili, è possibile chiamare 'subprocess.check_output ([" lsb_release "," - is "])'. – panzi

risposta

9

questo funziona per me su Ubuntu:

('Ubuntu', '10.04', 'lucid') 

Ho quindi utilizzato strace per scoprire che cosa esattamente il modulo della piattaforma sta facendo per trovare la distribuzione, ed è questa parte:

open("/etc/lsb-release", O_RDONLY|O_LARGEFILE) = 3 
fstat64(3, {st_mode=S_IFREG|0644, st_size=102, ...}) = 0 
fstat64(3, {st_mode=S_IFREG|0644, st_size=102, ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76b1000 
read(3, "DISTRIB_ID=Ubuntu\nDISTRIB_RELEAS"..., 8192) = 102 
read(3, "", 4096)      = 0 
read(3, "", 8192)      = 0 
close(3)        = 0 

Quindi, c'è /etc/lsb-release contenente queste informazioni, che proviene dal pacchetto Debian base-files di Ubuntu.

+0

Si noti che a volte il file è '/ etc/os-release'. – panzi

12

Here 's che cosa ho trovato:

platform.linux_distribution 

cerca di determinare il nome del sistema operativo Linux nome della distribuzione .

Dice platform.dist è deprecato dal 2.6, è necessario utilizzare platform.linux_distribution in Python 2 (ma è anche deprecato in Python 3.5).

0

due opzioni per voi:

  1. Usa piattaforma di importazione platform.linux_distribution() # Qualcosa di simile ('Ubuntu', '9.10', 'karmico')

  2. Oppure si potrebbe solo leggere il contenuto di/etc/debian_version ("squeeze/sid") o/etc/lsb-release che darebbe:

    DISTRIB_ID=Ubunt 
    DISTRIB_RELEASE=9.10 
    DISTRIB_CODENAME=karmic 
    DISTRIB_DESCRIPTION="Ubuntu 9.10" 
    
+0

Sfortunatamente, la prima opzione non funziona su Arch Linux. Al momento non ho accesso ad Arch, quindi non posso testare la seconda opzione. –

4

Funziona qui. E no, Arch Linux non è basato su Debian.

>>> import platform 
>>> platform.dist() 
('SuSE', '11.2', 'x86_64') 

Quindi Python non sa come ottenere le informazioni sulla release di Arch Linux, ed è alla ricerca di hardcoded/etc/redhat-release e/etc/SuSE-release.

platform.dist() è una funzione obsoleta. Dovresti usare la piattaforma.linux_distribution()

In realtà, sul mio sistema produce un risultato diverso:

>>> platform.linux_distribution() 
('openSUSE ', '11.2', 'x86_64') 

platform.linux_distribution() guarda in/etc file contenenti "release" o "versione" come stringa. Cerca anche nel file di rilascio LSB standard. Se alla fine non ha funzionato, ricorre a una funzione _dist_try_harder che tenta di ottenere le informazioni da altri posti.

Quindi è su Arch Linux fornire informazioni sulla versione LSB standard o patch Python per utilizzare il loro "modo".

-1

Probabilmente dovrete ricorrere a:

if platform.linux_distribution() == ('', '', ''): 
    # do something specific to look for Arch 

o si potrebbe sempre aumentare lib/python2.6/platform.py e inviare le modifiche.

+1

Questo tipo di confronto è pericoloso perché Arch Linux non è l'unica distribuzione che 'platform' non può rilevare. Amazon Linux genera anche una tupla vuota. –

1

questo ha lavorato per me sotto Ubuntu e Manjaro:

def get_distro(): 
    """ 
    Name of your Linux distro (in lowercase). 
    """ 
    with open("/etc/issue") as f: 
     return f.read().lower().split()[0] 
+0

Funziona su Arch Linux;) – nachopro

+1

non è una buona idea, '/ etc/issue' è per la riga di benvenuto show sulla console standard e molto spesso viene modificata dall'utente/admin. Il modo standard per rilevare la distro moderna è parse '/ etc/lsb-release' o meglio'/etc/os-release' –

0

Python 2 non rileva correttamente Arch Linux. Questo è stato risolto in Python 3.3+, ma non fu mai back-porting per Python 2. Qui ci sono un paio di rapporti ufficiali di bug:

https://bugs.python.org/issue20454
https://bugs.python.org/issue11678

Una soluzione per questo problema in Python 2 è abbastanza semplice. Hai solo bisogno di dire al modulo di piattaforma che "arco" è una distribuzione supportata:

>>> import platform 
>>> platform.linux_distribution(supported_dists=platform._supported_dists + ('arch',)) 
('arch', '', '') 

noti che Arch Linux è una rolling release, in modo che non dispone di una versione o id.

L'argomento supported_dists è documentato here, anche se non trovo la documentazione molto chiara. Non vuoi sovrascrivere _supported_dists perché il tuo codice sarà solo funziona su Arch Linux. Vuoi aggiungere alla tupla.

Infatti, se si stampa il valore di platform._supported_dists, si noterà che l'unica differenza tra Python 2.7.12 e Python 3.5.1 è l'aggiunta di ('arch', 'mageia'). Un fatto divertente: puoi anche aggiungere 'system' per il rilevamento della piattaforma su Amazon Linux.

2

Il motivo per cui lo platform.linux_distribution non identifica alcune distribuzioni è dovuto al fatto che le distribuzioni non standardizzate forniscono informazioni relative alla versione su se stesse.

Ho scritto un pacchetto chiamato distro (ora utilizzato da pip) che ha lo scopo di sostituire distro.linux_distribution. Funziona su molte distribuzioni che potrebbero restituire tuple strane o vuote quando si utilizza platform.

https://github.com/nir0s/distro (distro, su PyPI)

Fornisce un'API molto più elaborato per recuperare le informazioni relative distribuzione.

$ python 
Python 2.7.12 (default, Nov 7 2016, 11:55:55) 
[GCC 6.2.1 20160830] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import distro 
>>> distro.linux_distribution() 
(u'Antergos Linux', '', u'ARCHCODE') 

proposito, platform.linux_distribution deve essere rimosso in Python 3.7.

Problemi correlati