Wie finde ich heraus, welche Linux-Version ausgeführt wird?
29
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?
Mit Version meinen Sie die Kernel-Version? Welche Distribution? Die Distribution?
Chris Upchurch
2
Ich bin sicher, dass Jldugger herausfinden möchte, welche Distributionsfamilie das System ausführt. Es ist unwahrscheinlich, dass ein Skript von der Kernel-Version betroffen ist, es sei denn, es hängt von einigen / sys- oder / proc-Elementen ab - und selbst dann ist es in der Regel einfacher anzunehmen, dass es auf der Distribution basiert als auf dem Kernel.
Mihai Limbăşan
Antworten:
27
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.
(Erweitern Sie diese Antwort.) In einigen Situationen ist die Feature-Erkennung vorzuziehen. Versuchen Sie jedoch niemals, die Verteilung anhand der von Ihnen erkannten Features zu erraten! Verstehen Sie die Antwort nicht falsch und prüfen Sie anhand der Dateien in / etc, ob die Plattform RedHat ist. Wenn Sie den Distributionsnamen wirklich benötigen, überprüfen Sie lsb_release (oder / etc / redhat-release usw.).
Nicholas Wilson
36
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-versionInhalt prüfen
Überprüfen Sie im Allgemeinen auf /etc/*-releaseund /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 typeeingebauten Bash. type -tGibt zurück, functionob dieses Symbol eine Funktion ist. Wir stellen zzdie Ausgabe von voran , type -t 2>/dev/nullda 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:
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.
Ich habe nicht nachgeschaut, warum, aber es kehrt zu Debian Lenny (5.0) zurück.
Gareth
Gyaresu, haben Sie tatsächlich die Funktion get_distribution_type aufgerufen? Ich habe den Beitrag bearbeitet, um zu verdeutlichen (siehe unten).
Mihai Limbăşan
@gyaresu: Wenn dies nicht das Problem war, können Sie bitte versuchen, log_begin_msg im Debian-Abschnitt durch log_warning_msg zu ersetzen und es erneut zu versuchen? Möglicherweise wurde der Funktionsname falsch angegeben. Auf jeden Fall hätte es "unknown" zurückgeben sollen, wenn diese Funktion nicht vorhanden wäre, aber immer noch.
Mihai Limbăşan
@Mihai Doh! Es tut uns leid. Ich habe das Drehbuch nicht richtig gelesen. War früh, kein Kaffee. Ich entschuldige mich. gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth
@gyaresu: Danke! Das ist gut, sollte Jldugger helfen zu wissen, dass es auch auf Debian funktioniert :)
Mihai Limbăşan
17
Sie können die Kernel-Version finden, indem Sie uname -aausfü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
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.
Großartige Idee. Ich würde die Verwendung empfehlen python -c 'import platform; print(platform.dist()[0])', da dies auch funktioniert, wenn das normale Python standardmäßig python3 ist.
Heinrich5991
5
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.
Es mag nicht optimal sein, aber es ist an der gleichen Stelle.
Brad Gilbert
4
facter ist ein praktisches Werkzeug für diese Art der Entdeckung, obwohl es wahrscheinlich einige der oben beschriebenen Methoden verwendet und Ruby benötigt.
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:
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.
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.
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.
quelle
Es gibt keinen Querverteilungsweg. Jedoch:
Ü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.
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:
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:
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.
quelle
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 lesenDebian speichert die Version in / etc / debian_version
quelle
Die meisten Distributionen verfügen über eine einzigartige Methode zur Bestimmung der jeweiligen Verteilung.
Beispielsweise:
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.
quelle
lsb_release
gibt es nicht auf CentOS 6.Code: http://hg.python.org/cpython/file/2.7/Lib/platform.py
quelle
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 .:
Und ja, ich weiß, dass es nicht optimal ist. :)
quelle
facter ist ein praktisches Werkzeug für diese Art der Entdeckung, obwohl es wahrscheinlich einige der oben beschriebenen Methoden verwendet und Ruby benötigt.
quelle
Sie müssen nur
uname -a
Ihre Lieblingsshell eingeben. Dadurch werden der Name und die Version des Kernels ausgedruckt.quelle
Ich habe festgestellt, dass
cat /etc/*release*
fast immer funktioniert.quelle
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.
quelle
Sie können die Version auch von erhalten
O / P:
quelle
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:quelle
Du kannst auch im Grub-Menü nachschauen, normalerweise gibt es ein paar Informationen zur Distribution / Version :-)
quelle
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.
quelle