Manchmal müssen sich Ihre Skripte unter verschiedenen Linux-Betriebssystemen anders verhalten. Wie kann ich feststellen, auf welcher Linux-Version ein Skript ausgeführt wird?
Manchmal müssen sich Ihre Skripte unter verschiedenen Linux-Betriebssystemen anders verhalten. Wie kann ich feststellen, auf welcher Linux-Version ein Skript ausgeführt wird?
Antworten:
Versuchen Sie nicht, Annahmen zu treffen, die auf der Distribution basieren, was Sie können und was nicht, denn auf diese Weise liegt der Wahnsinn (siehe auch "Benutzeragentenerkennung"). Ermitteln Sie stattdessen, ob das, was Sie tun möchten, unterstützt wird und wie es von dem Befehl oder Dateispeicherort ausgeführt wird, den Sie verwenden möchten.
Wenn Sie beispielsweise ein Paket installieren möchten, können Sie feststellen, ob Sie sich auf einem Debian-ähnlichen System oder einem RedHat-ähnlichen System befinden, indem Sie prüfen, ob dpkg oder rpm vorhanden ist (prüfen Sie zuerst, ob dpkg vorhanden ist, da dies auf Debian-Maschinen möglich ist den rpm Befehl auf sie ...). Treffen Sie Ihre Entscheidung, was Sie darauf basierend tun möchten, nicht nur, ob es sich um ein Debian- oder ein RedHat-System handelt. Auf diese Weise werden automatisch alle abgeleiteten Distributionen unterstützt, die Sie nicht explizit programmiert haben. Oh, und wenn Ihr Paket bestimmte Abhängigkeiten erfordert, testen Sie auch diese und lassen Sie den Benutzer wissen, was sie vermissen.
Ein anderes Beispiel ist das Spielen mit Netzwerkschnittstellen. Ermitteln Sie anhand der Datei / etc / network / interfaces oder des Verzeichnisses / etc / sysconfig / network-scripts, was zu tun ist, und wechseln Sie von dort aus.
Ja, es ist mehr Arbeit, aber wenn Sie nicht alle Fehler, die Webentwickler in den letzten zehn oder mehr Jahren gemacht haben, erneut machen möchten, tun Sie dies von Anfang an auf intelligente Weise.
Es gibt keinen Querverteilungsweg. Jedoch:
- Redhat und Freunde: Testen Sie auf
/etc/redhat-release
, überprüfen Sie den Inhalt- Debian: Testen Sie auf
/etc/debian_version
, überprüfen Sie den Inhalt- Mandriva und Freunde: Teste
/etc/version
, überprüfe den Inhalt- Slackware: Auf
/etc/slackware-version
Inhalt prüfen
Überprüfen Sie im Allgemeinen auf /etc/*-release
und /etc/*-version
.
Bearbeiten: Ich habe ein altes (1+ Jahre) Bash-Skript gefunden, das ich im Laufe der Jahre zusammengeschustert haben muss (es hat ein beeindruckendes CVS-Protokoll, das 6 Jahre zurückliegt.) Es funktioniert möglicherweise nicht mehr richtig wie es ist und ich kann Sie müssen keine installierten Distributionen zum Testen finden, aber sie sollten Ihnen einen guten Ausgangspunkt bieten. Es funktioniert gut auf CentOS, Fedora und Gentoo. gyaresu hat es erfolgreich auf Debian Lenny getestet.
#!/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
}
Beachten Sie, dass dies wahrscheinlich nur in Bash korrekt funktioniert. Sie könnten es für andere Shells umschreiben.
Abgesehen davon möchten Sie möglicherweise auf Features testen, nicht auf Distributionen. Ich benutze dies nicht mehr, nur weil es eine Wartungslast wurde. Es ist einfacher, sich auf verteilungsübergreifende Tools und Lösungen zu verlassen.
Konzeptionell ist das, was es tut, in der Reihenfolge:
- Rufen Sie einen bekannten Dateityp "Common Init Script Function" auf. Diese sind vertriebsspezifisch. Ist dies nicht der Fall, fahren Sie mit der nächsten Überprüfung der Verteilung fort.
- Überprüfen Sie, ob eine bestimmte, bekanntermaßen vorhandene, häufig verwendete und wahrscheinlich nicht umbenannte Funktion in diesem Kernskript vorhanden ist. Wir machen das mit dem
type
eingebauten Bash.type -t
Gibt zurück,function
ob dieses Symbol eine Funktion ist. Wir stellenzz
die Ausgabe von voran ,type -t 2>/dev/null
da die Ausgabezeichenfolge leer ist, wenn der Name nicht definiert ist, und dem==
Operator ein Syntaxfehler über eine fehlende linke Hand angezeigt wird. Wenn der gerade überprüfte Name keine Funktion ist, fahren Sie mit der nächsten Verteilungsüberprüfung fort, andernfalls haben wir den Verteilungstyp gefunden.- Geben Sie abschließend den Verteilungstyp wieder, damit der Funktionsausgang in einem case .. esac-Block problemlos verwendet werden kann.
Bearbeiten Sie, falls Sie dies als direktes Skript ausführen möchten: Dieses Skript soll von anderen Skripten bezogen oder eingeschlossen werden. Es gibt nichts aus, wenn Sie es so ausführen, wie es ist. Um es zu testen, geben Sie es als Quelle ein und rufen Sie dann die Funktion auf, zB:
source /path/to/this/script.sh
get_distribution_type
an der Bash-Eingabeaufforderung.
Bearbeiten: Bitte beachten Sie, dass für dieses Skript keine Root-Rechte erforderlich sind. Ich fordere Sie auf, es nicht als root auszuführen. Sollte nichts schaden, aber es gibt keine Notwendigkeit.
Es wurde ein Link zu einem relevanten Post in der Mailingliste im CVS-Protokoll gefunden. Sollte beim Auspacken von Init-Skript-Spaghetti hilfreich sein.
Sie können die Kernel-Version finden, indem Sie uname -a
ausführen. Die Ermittlung der Distribution-Version hängt von der Distribution ab.
Unter Ubuntu und anderen Betriebssystemen können Sie lsb_release -a
/ etc / lsb_release ausführen oder lesen
Debian speichert die Version in / etc / debian_version
Die meisten Distributionen verfügen über eine einzigartige Methode zur Bestimmung der jeweiligen Verteilung.
Beispielsweise:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
Es gibt einen Standard, der als Linux Standard Base oder LSB bekannt ist . Es definiert, dass es eine Datei mit dem Namen / etc / lsb-release oder ein Programm mit dem Namen lsb_release geben soll, die Informationen über Ihre Linux-Distribution zurückliefert.
lsb_release -a
lsb_release
gibt es nicht auf CentOS 6.
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
, da dies auch funktioniert, wenn das normale Python standardmäßig python3 ist.
Zusätzlich zu den anderen Antworten: Wenn Sie nur eine Datei analysieren möchten, personalisieren die meisten Distributionen das tty-Login über / etc / issue, z. B .:
Willkommen bei SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel.
Und ja, ich weiß, dass es nicht optimal ist. :)
Sie müssen nur uname -a
Ihre Lieblingsshell eingeben. Dadurch werden der Name und die Version des Kernels ausgedruckt.
Ich stimme Mark, Adam und Mihai zu (kann wegen unzureichenden Rufs nicht abstimmen). Lösungen, die auf LSB und der zugehörigen FHS basieren, funktionieren mit den meisten Distributionen und werden wahrscheinlich auch in Zukunft funktionieren. LSB und FHS sind deine Freunde.
Die Version von Linux ist eine schwierige Frage. Wenn wir es uns genauer ansehen, haben wir die Kernel-Version, die Sie mit " uname -r
" erhalten können. Die Distributionsversion ist meist irrelevant. Einige Distributionen sind besser (Unternehmensdistributionen wie Redhat Enterprise Linux). Andere Distributionen wie Gentoo sind im Grunde genommen bewegliche Ziele, die überhaupt keine vernünftige Version haben. Wenn Sie Dinge basierend auf der Version tun müssen, werfen Sie einen Blick auf wichtige Komponenten, die für Sie relevant sind:
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...
Du kannst auch im Grub-Menü nachschauen, normalerweise gibt es ein paar Informationen zur Distribution / Version :-)
FusionInventory ist ein plattformübergreifendes, kompaktes Inventur-Tool, mit dem diese Informationen auf vielen Linux-Distributionen, aber auch auf BSDs, Windows, MacOS X und anderen Unices abgerufen werden können.
Falls verfügbar, verwenden sie lsb_release
(wie oben bereits erwähnt) eine sehr nützliche Liste von Dateien und regulären Ausdrücken, um den Namen und die Version der Distribution zu überprüfen: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Eingabe / Linux / Distro / NonLSB.pm # L16 .
Ich würde empfehlen, FusionInventory selbst zu verwenden, um diese Informationen abzurufen, anstatt Ihre eigenen Skripte mit dieser Logik erneut zu implementieren, da die Community diese Funktionalität auf dem neuesten Stand hält. Sie können den Agenten entweder allein verwenden (er gibt eine einfach zu analysierende XML / JSON-Datei aus) oder ihn mit einer umfassenderen Lösung koppeln, um die Computer in Ihrem Netzwerk wie GLPI oder Rudder zu verwalten , je nach Ihren Anforderungen.