A volte i tuoi script devono comportarsi diversamente su Linux diversi. Come posso determinare su quale versione di Linux è in esecuzione uno script?
A volte i tuoi script devono comportarsi diversamente su Linux diversi. Come posso determinare su quale versione di Linux è in esecuzione uno script?
Risposte:
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.
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/*-release
e /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
type
Bash incorporato.type -t
ritornafunction
se quel simbolo è una funzione. Anticipiamozz
l'outputtype -t 2>/dev/null
perché 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.
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 -a
o leggere / etc / lsb_release
Debian memorizza la versione in / etc / debian_version
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
lsb_release
non esiste su CentOS 6.
python -c 'import platform ; print platform.dist()[0]'
codice: http://hg.python.org/cpython/file/2.7/Lib/platform.py
python -c 'import platform; print(platform.dist()[0])'
, perché in questo modo funziona anche se il normale python è impostato su python3.
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. :)
Tutto quello che devi fare è digitare la uname -a
tua shell preferita. Questo stamperà il nome e la versione del kernel.
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.
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...
Puoi anche controllare il menu di Grub, di solito ti dà un sacco di informazioni sulla versione / distribuzione :-)
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.