Frage Wie finde ich heraus, welche Version von Linux läuft?


Manchmal müssen sich Ihre Skripte auf verschiedenen Linux-Systemen anders verhalten. Wie kann ich feststellen, auf welcher Linux-Version ein Skript ausgeführt wird?


29
2018-05-02 23:11


Ursprung


Mit Version meinst du die Kernel-Version? Welche Verteilung? Die Distributionsversion? - Chris Upchurch
Ich bin mir sicher, dass jldugger herausfinden möchte, welche Distributionsfamilie das System betreibt. Es ist unwahrscheinlich, dass ein Skript von der Kernel-Version beeinflusst wird, es sei denn, es hängt von einigen / sys- oder / proc-Dingen ab - und selbst dann ist es normalerweise einfacher, basierend auf der Distribution als auf dem Kernel zu denken. - Mihai Limbăşan


Antworten:


Versuchen Sie nicht, auf der Grundlage der Distribution Annahmen zu treffen, was Sie tun können und was nicht, denn so liegt der Wahnsinn (siehe auch "User Agent Detection"). Ermitteln Sie stattdessen, ob das, was Sie tun möchten, unterstützt wird und wie es von welchem ​​Befehl oder Dateispeicherort verwendet wird.

Wenn Sie beispielsweise ein Paket installieren möchten, können Sie feststellen, ob Sie auf einem Debian-ähnlichen System oder einem RedHat-ähnlichen System sind, indem Sie nach dpkg oder rpm suchen (überprüfen Sie zuerst dpkg, da Debian-Maschinen dies können) der Befehl rpm auf ihnen ...). Entscheiden Sie, was zu tun ist, nicht nur, ob es sich um ein Debian- oder RedHat-System handelt. Auf diese Weise werden Sie automatisch alle abgeleiteten Distributionen unterstützen, die Sie nicht explizit programmiert haben. Oh, und wenn Ihr Paket bestimmte Abhängigkeiten erfordert, dann testen Sie auch diese und lassen Sie den Benutzer wissen, was ihnen fehlt.

Ein anderes Beispiel ist das Hantieren mit Netzwerkschnittstellen. Finde heraus, was zu tun ist, abhängig davon, ob es eine Datei / etc / network / interfaces oder ein Verzeichnis / etc / sysconfig / network-scripts gibt und gehe von dort.

Ja, es ist mehr Arbeit, aber wenn Sie nicht alle Fehler, die Webentwickler in den letzten zehn Jahren oder mehr gemacht haben, neu machen wollen, werden Sie es von Anfang an auf intelligente Weise tun.


27
2018-05-03 00:06



(Erweitern Sie diese Antwort) Feature-Erkennung ist in einigen Situationen vorzuziehen, aber stellen Sie sicher, dass Sie nie versuchen, die Verteilung von den Features, die Sie erkennen, zu erraten! Lesen Sie die Antwort nicht falsch und ermitteln Sie anhand der Dateien in / etc, ob die Plattform RedHat ist. Wenn Sie den Verteilungsnamen wirklich benötigen, überprüfen Sie lsb_release (oder / etc / redhat-release usw.). - Nicholas Wilson


Es gibt keinen übergreifenden Weg. Jedoch:

  • Redhat und Freunde: Test auf / etc / redhat-release, Inhalt prüfen
  • Debian: Auf / etc / debian_version testen, Inhalt prüfen
  • Mandriva und Freunde: Test für / etc / version, Inhalt überprüfen
  • Slackware: Test auf / etc / slackware-version, Inhalt prüfen

Etc. In der Regel überprüfen Sie für /etc/*-release und /etc/*-version.


Edit: Ich habe ein altes (1+ Jahre) Bash-Skript von mir gefunden, das ich im Laufe der Jahre zusammengeschustert habe (es hat ein beeindruckendes CVS-Protokoll, das 6 Jahre zurückreicht.) Es funktioniert vielleicht nicht mehr so ​​wie es ist und ich kann Es wird nicht darauf ankommen, installierte Distributionen zu finden, um zu testen, aber es sollte Ihnen einen guten Ausgangspunkt bieten. Es funktioniert gut auf CentOS, Fedora und Gentoo. gyaresu testete es erfolgreich auf 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
}

Beachten Sie, dass dies wahrscheinlich nur in Bash funktioniert. Sie könnten es von anderen Schalen umschreiben.

Davon abgesehen möchten Sie möglicherweise nach Features suchen, nicht nach Distributionen. Ich benutze das nicht mehr, nur weil es eine Wartungslast wurde. Es ist einfacher, sich auf verteilungsübergreifende Tools und Lösungen zu verlassen.


Konzeptionell ist es in der Reihenfolge:

  • Ziehe eine bekannte Art von "common init script function" -Datei ein. Diese sind verteilungsspezifisch. Wenn es nicht existiert, springen Sie zur nächsten Verteilungsprüfung.
  • Überprüfen Sie das Vorhandensein einer bestimmten, bekanntermaßen vorhandenen, häufig verwendeten und unwahrscheinlich umbenannten Funktion aus diesem Kernskript. Wir machen das mit dem typeBash eingebaut. type -t kehrt zurück function wenn dieses Symbol eine Funktion ist. Wir machen vor zz zum Ausgang von type -t 2>/dev/null weil, wenn der Name nicht definiert ist, die Ausgabezeichenfolge leer wäre und wir einen Syntaxfehler über eine fehlende linke Hand erhalten würden == Operator. Wenn der gerade überprüfte Name keine Funktion ist, springen Sie zur nächsten Verteilungsprüfung, andernfalls finden wir den Verteilungstyp.
  • Schließlich, Echo der Verteilungstyp, so dass die Funktion Ausgabe kann in einem Fall einfach verwendet werden .. esac Block.

Bearbeiten, falls Sie versuchen, dies als ein direktes Skript auszuführen: Dieses Skript soll von anderen Skripten bezogen oder einbezogen werden. Es wird nichts ausgegeben, wenn Sie es unverändert ausführen. Um es zu testen, rufen Sie es ab und rufen Sie dann die Funktion auf, z.

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

bei der Bash-Eingabeaufforderung.


Edit: Bitte beachten Sie, dass dieses Skript keine Root-Rechte benötigt. Ich fordere Sie auf, es nicht als Wurzel zu führen. Sollte nichts schaden, aber es gibt keine Notwendigkeit.


Gefunden einen Link zu einem relevanten Mailinglistenpost im CVS-Protokoll. Sollte beim Auspacken von Init-Skript-Spaghetti nützlich sein.


36
2018-05-02 23:15



Ich habe nicht nach dem Grund gesucht, aber es kehrt zurück zu Debian Lenny (5.0). - Gareth
gyaresu, hast du tatsächlich die Funktion get_distribution_type aufgerufen? Ich habe den Beitrag zur Klärung bearbeitet (siehe unten). - Mihai Limbăşan
@ gyaresu: Wenn das obige nicht das Problem war, kannst du bitte versuchen, log_begin_msg im Debian-Bereich durch log_warning_msg zu ersetzen und es erneut zu versuchen? Könnte den Funktionsnamen falsch bekommen haben. In jedem Fall sollte es "unbekannt" zurückgegeben haben, wenn diese Funktion nicht here, aber immer noch war. - Mihai Limbăşan
@Mihai Doh! Es tut uns leid. Ich habe das Skript nicht richtig gelesen. War früh, kein Kaffee. Ich entschuldige mich. gyaresu @ debian: ~ / bin $ Quelle 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


Sie können die Kernel-Version finden, indem Sie ausführen uname -aDas Auffinden der Distro-Version hängt von der Distribution ab.

Unter Ubuntu und einigen anderen Betriebssystemen können Sie laufen lsb_release -a oder lesen Sie / etc / lsb_release

Debian speichert die Version in / etc / debian_version


17
2018-05-02 23:14



+1 für lsb_release (funktioniert auch auf Red Hat-Derivaten, wenn das richtige Paket installiert ist) - Josh Kelley
für nur die Beschreibung 'lsb_release -ds'. - flickerfly


Die meisten Distributionen haben eine einzigartige Methode zur Bestimmung der jeweiligen Distribution.

Zum Beispiel:

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

SUSE: /etc/SUSE-release

Es gibt einen Standard, der als der bekannt ist Linux Standardbasis oder LSB. Es definiert, dass es eine Datei namens / etc / lsb-release oder ein Programm namens lsb_release geben sollte, das Informationen über Ihre Linux-Distribution zurückgibt.

lsb_release -a

6
2018-05-02 23:24



Und natürlich, lsb_release existiert nicht auf CentOS 6. - Justin


python -c 'import platform ; print platform.dist()[0]'

Code: http://hg.python.org/cpython/file/2.7/Lib/platform.py


6
2017-09-19 02:14



Großartige Idee. Ich würde vorschlagen, zu verwenden python -c 'import platform; print(platform.dist()[0])', denn so funktioniert es auch, wenn der normale Python standardmäßig auf python3 gesetzt ist. - heinrich5991


Zusätzlich zu den anderen Antworten: Wenn Sie nur eine Datei analysieren wollen, personalisieren die meisten Distributionen den tty-Login über / etc / issue.

Willkommen bei SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).

Und ja, ich weiß, dass es suboptimal ist. :)


5
2018-05-02 23:21



Es kann suboptimal sein, aber es ist an der gleichen Stelle. - Brad Gilbert


Faktor ist ein praktisches Werkzeug für diese Art der Suche, obwohl es wahrscheinlich einige der oben beschriebenen Methoden verwendet und Ruby benötigt.


4
2018-05-05 00:52





Alles, was Sie tun müssen, ist tippen uname -a in deiner Lieblingsmuschel. Dadurch werden der Name und die Version des Kernels ausgegeben.


2
2018-05-05 01:41