Soluzione 1:
Non esiste un modo di distribuzione incrociata. Tuttavia:
- Redhat e amici:test 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 bash (1+ anni) in giro che devo aver messo insieme nel corso degli anni (ha un registro CVS impressionante che risale a 6 anni fa). Potrebbe non funzionare più correttamente così com'è e posso non preoccuparti di trovare distribuzioni installate su cui testare, ma dovrebbe fornirti un buon punto di partenza. Funziona bene su CentOS, Fedora e Gentoo. gyaresu l'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, quello che fa è, nell'ordine:
- Inserisce un tipo di file noto, "comune init script function". Quelli sono specifici della distribuzione. Se non esiste, passa al prossimo controllo di distribuzione.
- Controlla l'esistenza di una funzione specifica, nota per esistere, usata spesso e che difficilmente verrà rinominata da quello script principale. Lo facciamo usando il
type
Bash incorporato.type -t
restituiscefunction
se quel simbolo è una funzione. Anteponiamozz
all'output ditype -t 2>/dev/null
perché se il nome non è definito la stringa di output sarebbe vuota e otterremmo un errore di sintassi su una mano sinistra mancante al==
operatore. Se il nome che abbiamo appena controllato 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 tentando di eseguirlo come uno script diretto:questo script dovrebbe essere originato o incluso da altri script. Non emette nulla da solo se lo esegui così com'è. Per testarlo, creane una fonte e quindi invoca la funzione, ad esempio:
source /path/to/this/script.sh
get_distribution_type
al prompt di bash.
Modifica:tieni presente che questo script non richiede i privilegi di root. Ti esorto a non eseguirlo come root. Non dovrebbe danneggiare nulla, ma non ce n'è bisogno.
Trovato un collegamento a un post della mailing list pertinente nel registro CVS. Dovrebbe essere utile per scartare gli spaghetti degli script init.
Soluzione 2:
Non cercare di fare ipotesi basate sulla distribuzione su ciò che puoi e non puoi fare, perché in questo modo si trova la follia (vedi anche "Rilevamento dell'agente utente"). Invece, rileva se ciò che vuoi fare è supportato e come viene fatto da qualunque comando o percorso di file che vuoi usare.
Ad esempio, se si desidera installare un pacchetto, è possibile rilevare se ci si trova su un sistema simile a Debian o a un sistema simile a RedHat controllando l'esistenza di dpkg o rpm (verificare prima dpkg, perché le macchine Debian possono avere il comando rpm su di essi...). Prendi la tua decisione su cosa fare in base a questo, non solo se si tratta di un sistema Debian o RedHat. In questo modo supporterai automaticamente tutte le distribuzioni derivate in cui non hai programmato esplicitamente. Oh, e se il tuo pacchetto richiede dipendenze specifiche, prova anche quelle e fai sapere all'utente cosa si perde.
Un altro esempio è armeggiare con le interfacce di rete. Stabilisci cosa fare in base alla presenza di un file /etc/network/interfaces o di una directory /etc/sysconfig/network-scripts e prosegui da lì.
Sì, è più impegnativo, ma a meno che tu non voglia ripetere tutti gli errori che gli sviluppatori web hanno commesso nell'ultimo decennio o più, lo farai in modo intelligente fin dall'inizio.
Soluzione 3:
Puoi trovare la versione del kernel eseguendo uname -a
, trovare la versione della distribuzione dipende dalla distribuzione.
Su Ubuntu e altri sistemi operativi puoi eseguire lsb_release -a
o leggi /etc/lsb_release
Debian memorizza la versione in /etc/debian_version
Soluzione 4:
La maggior parte delle distribuzioni ha un metodo unico per determinare la particolare distribuzione.
Ad esempio:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
Esiste uno standard là fuori noto come Linux Standard Base o LSB. Definisce che dovrebbe esserci un file chiamato /etc/lsb-release o un programma chiamato lsb_release che restituirà le informazioni sulla tua distribuzione Linux.
lsb_release -a
Soluzione 5:
python -c 'import platform ; print platform.dist()[0]'
codice:http://hg.python.org/cpython/file/2.7/Lib/platform.py