Come faccio a sapere quale versione di Linux è in esecuzione?


29

A volte i tuoi script devono comportarsi diversamente su Linux diversi. Come posso determinare su quale versione di Linux è in esecuzione uno script?


1
Per versione, intendi la versione del kernel? Quale distribuzione? La versione distro?
Chris Upchurch,

2
Sono sicuro che jldugger vuole scoprire quale famiglia di distribuzione è in esecuzione sul sistema. È improbabile che uno script sia influenzato dalla versione del kernel a meno che non dipenda da alcune cose / sys o / proc - e anche in questo caso è solitamente più facile supporre in base alla distribuzione che al kernel.
Mihai Limbăşan,

Risposte:


27

Non cercare di fare ipotesi basate sulla distro su ciò che puoi e non puoi fare, in questo modo sta la follia (vedi anche "Rilevamento User Agent"). Rileva invece se è supportato ciò che vuoi fare e come viene eseguito dal comando o dalla posizione del file che desideri utilizzare.

Ad esempio, se si desidera installare un pacchetto, è possibile rilevare se ci si trova su un sistema simile a Debian o su un sistema simile a RedHat verificando l'esistenza di dpkg o rpm (verificare innanzitutto che sia presente dpkg, poiché le macchine Debian possono avere il comando rpm su di loro ...). Prendi la tua decisione su cosa fare in base a quello, non solo se si tratta di un sistema Debian o RedHat. In questo modo supporterai automaticamente tutte le distro derivate che non hai programmato esplicitamente. Oh, e se il tuo pacchetto richiede dipendenze specifiche, prova anche quelle e fai sapere all'utente cosa mancano.

Un altro esempio è giocherellare con le interfacce di rete. Scopri cosa fare in base al file / etc / network / interfaces o alla directory / etc / sysconfig / network-scripts e vai da lì.

Sì, è più lavoro, ma a meno che tu non voglia rifare tutti gli errori che gli sviluppatori web hanno fatto negli ultimi dieci anni o più, lo farai in modo intelligente fin dall'inizio.


1
(Espandendo su questa risposta) Il rilevamento delle caratteristiche è preferibile in alcune situazioni, ma assicurati di non provare mai a indovinare la distribuzione dalle caratteristiche che rilevi! Non leggere male la risposta e capire se la piattaforma è RedHat in base ai file in / etc. Se hai davvero bisogno del nome di distribuzione, controlla lsb_release (o / etc / redhat-release e così via).
Nicholas Wilson,

36

Non esiste un modo di distribuzione incrociata. Tuttavia:

  • Redhat e amici: prova per /etc/redhat-release, controlla i contenuti
  • Debian: prova per /etc/debian_version, controlla i contenuti
  • Mandriva e amici: prova per /etc/version, controlla i contenuti
  • Slackware: prova per /etc/slackware-version, controlla i contenuti

Ecc. In generale, controlla /etc/*-releasee /etc/*-version.


Modifica: ho trovato un mio vecchio script (1+ anni) bash in giro che devo aver messo insieme nel corso degli anni (ha un registro CVS impressionante che risale a 6 anni.) Potrebbe non funzionare più correttamente così com'è e posso non preoccuparti di trovare distro installate per testare, ma dovrebbe fornirti un buon punto di partenza. Funziona bene su CentOS, Fedora e Gentoo. gyaresu lo ha testato con successo su Debian Lenny.

#!/bin/bash

get_distribution_type()
{
    local dtype
    # Assume unknown
    dtype="unknown"

    # First test against Fedora / RHEL / CentOS / generic Redhat derivative
    if [ -r /etc/rc.d/init.d/functions ]; then
        source /etc/rc.d/init.d/functions
        [ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"

    # Then test against SUSE (must be after Redhat,
    # I've seen rc.status on Ubuntu I think? TODO: Recheck that)
    elif [ -r /etc/rc.status ]; then
        source /etc/rc.status
        [ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"

    # Then test against Debian, Ubuntu and friends
    elif [ -r /lib/lsb/init-functions ]; then
        source /lib/lsb/init-functions
        [ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"

    # Then test against Gentoo
    elif [ -r /etc/init.d/functions.sh ]; then
        source /etc/init.d/functions.sh
        [ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"

    # For Slackware we currently just test if /etc/slackware-version exists
    # and isn't empty (TODO: Find a better way :)
    elif [ -s /etc/slackware-version ]; then
        dtype="slackware"
    fi
    echo $dtype
}

Nota che probabilmente funzionerà correttamente solo in Bash. Potresti riscriverlo per altre shell.

Detto questo, potresti voler testare le funzionalità, non le distribuzioni. Non lo uso più semplicemente perché è diventato un onere di manutenzione. È più facile affidarsi a strumenti e soluzioni di distribuzione incrociata.


Concettualmente, ciò che fa è, al fine di:

  • Inserire un tipo di file noto, "common init script function". Quelli sono specifici della distribuzione. Se non esiste, passa al controllo di distribuzione successivo.
  • Verifica l'esistenza di una funzione specifica, nota per esistere, spesso usata e che probabilmente non verrà rinominata da quello script principale. Lo facciamo usando il typeBash incorporato. type -tritorna functionse quel simbolo è una funzione. Anticipiamo zzl'output type -t 2>/dev/nullperché se il nome non fosse definito la stringa di output sarebbe vuota e otterremmo un errore di sintassi su una mano sinistra mancante per l' ==operatore. Se il nome che abbiamo appena verificato non è una funzione, passa al controllo di distribuzione successivo, altrimenti abbiamo trovato il tipo di distribuzione.
  • Infine, fai eco al tipo di distribuzione in modo che l'output della funzione possa essere facilmente utilizzato in un blocco case .. esac.

Modifica nel caso in cui tu stia provando a eseguirlo come uno script diretto: questo script dovrebbe essere ottenuto o incluso da altri script. Non emette nulla da solo se lo si esegue così com'è. Per testarlo, procuratelo e quindi invocate la funzione, ad esempio:

source /path/to/this/script.sh
get_distribution_type

al prompt di bash.


Modifica: si noti che questo script non richiede i privilegi di root. Ti esorto a non eseguirlo come root. Non dovrebbe danneggiare nulla, ma non è necessario.


È stato trovato un collegamento a un post della mailing list pertinente nel registro CVS. Dovrebbe essere utile per scartare gli spaghetti di script di init.


Non ho esaminato il perché, ma torna a richiedere Debian Lenny (5.0).
Gareth

gyaresu, hai effettivamente invocato la funzione get_distribution_type? Ho modificato il post per chiarire (vedi in fondo.)
Mihai Limbăşan,

@gyaresu: se quanto sopra non era il problema, puoi provare a sostituire log_begin_msg nella sezione Debian con log_warning_msg e riprovare? Potrebbe avere sbagliato il nome della funzione. In ogni caso, avrebbe dovuto restituire "sconosciuto" se quella funzione non fosse ancora, ma comunque.
Mihai Limbăşan,

@Mihai Doh! Scusate. Non ho letto correttamente lo script. Era presto, niente caffè. Mi scuso. gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth

@gyaresu: grazie! Bene, dovrebbe aiutare i jugger a sapere che funziona anche su Debian :)
Mihai Limbăşan,

17

Puoi trovare la versione del kernel eseguendo uname -a, trovando che la versione della distro dipende dalla distro.

Su Ubuntu e su qualche altro SO 'puoi eseguire lsb_release -ao leggere / etc / lsb_release

Debian memorizza la versione in / etc / debian_version


+1 per lsb_release (funziona anche su derivati ​​Red Hat se è installato il pacchetto giusto)
Josh Kelley,

solo per la descrizione 'lsb_release -ds'.
flickerfly,

6

La maggior parte delle distro ha un metodo unico per determinare la distribuzione particolare.

Per esempio:

Redhat (And derivatives): /etc/redhat-release

SUSE: /etc/SUSE-release

Esiste uno standard conosciuto come Linux Standard Base o LSB . Definisce che dovrebbe esserci un file chiamato / etc / lsb-release o un programma chiamato lsb_release che restituirà informazioni sulla tua distribuzione Linux.

lsb_release -a

E ovviamente, lsb_releasenon esiste su CentOS 6.
Justin il


5

Oltre alle altre risposte: se vuoi solo analizzare un file, la maggior parte delle distribuzioni personalizza il login tty tramite / etc / issue, ad esempio:

Benvenuti in SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).

E sì, lo so che non è ottimale. :)


Potrebbe non essere ottimale, ma si trova nello stesso posto.
Brad Gilbert,

4

facter è uno strumento utile per questo tipo di scoperta, anche se probabilmente utilizza alcuni dei metodi descritti sopra e richiede Ruby.


2

Tutto quello che devi fare è digitare la uname -atua shell preferita. Questo stamperà il nome e la versione del kernel.


2

Ho scoperto che funziona cat /etc/*release*quasi sempre.


2

Concordo con Mark, Adam e Mihai (non posso votare a causa dell'insufficiente reputazione). Le soluzioni basate su LSB e il relativo FHS funzioneranno con la maggior parte delle distribuzioni e probabilmente continueranno a funzionare in futuro. LSB e FHS sono i tuoi amici.


2

Puoi anche ottenere la versione di

cat /proc/version

operazione:

Versione Linux 2.6.17-13mdv (rtp@octopus.mandriva.com) (versione gcc 4.1.2 20070302 (pre-release) (4.1.2-1mdv2007.1)) # 1 SMP ven 23 marzo 19:03:31 UTC 2007


1

La versione di Linux è una domanda difficile. Se lo guardiamo da vicino, abbiamo la versione del kernel che puoi ottenere con " uname -r". La versione di distribuzione è per lo più irrilevante. Alcune distribuzioni sono migliori (distribuzioni aziendali come Redhat Enterprise Linux). Altre distribuzioni come Gentoo sono sostanzialmente obiettivi mobili che non hanno alcuna versione ragionevole. Se devi fare le cose in base alla versione, dai un'occhiata ai principali componenti che sono rilevanti per te:

Component       Version command
glibc           /lib/libc.so.6
gcc             gcc --version
X               xdpyinfo
libX11          pkg-config --modversion x11
gtk+            pkg-config --modversion gtk+-2.0
qt-4            pkg-config --modversion QtCore

   etc...

1

Puoi anche controllare il menu di Grub, di solito ti dà un sacco di informazioni sulla versione / distribuzione :-)


-1

FusionInventory è uno strumento di inventario leggero multipiattaforma in grado di ottenere queste informazioni su molte distro Linux, ma anche su BSD, Windows, MacOS X e altri computer.

Se disponibili, usano lsb_release(come menzionato alcune volte sopra), ma in caso contrario hanno un elenco molto utile di file ed espressioni regolari per controllare il nome e la versione della distribuzione: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .

Consiglio di utilizzare FusionInventory stesso per ottenere queste informazioni, piuttosto che reimplementare i propri script con questa logica, poiché la loro comunità manterrà questa funzionalità aggiornata. Puoi usare l'agente da solo (genera un file XML / JSON che è facile da analizzare) o accoppiarlo con una soluzione più ampia per gestire le macchine della tua rete come GLPI o Rudder , a seconda delle tue esigenze.


Questa sarebbe una buona soluzione se non avesse dipendenze esterne dei moduli Perl
Will Sheppard
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.