Comment savoir quelle version de Linux fonctionne?

29

Parfois, vos scripts doivent se comporter différemment sur différents Linux. Comment puis-je déterminer sur quelle version de Linux un script s'exécute?

jldugger
la source
1
Par version, voulez-vous dire la version du noyau? Quelle distribution? La version distro?
Chris Upchurch
2
Je suis sûr que jldugger veut savoir quelle famille de distribution le système exécute. Il est peu probable qu'un script soit affecté par la version du noyau à moins qu'il ne dépende de certaines choses / sys ou / proc - et même alors, il est généralement plus facile de supposer en fonction de la distribution que du noyau.
Mihai Limbăşan

Réponses:

27

N'essayez pas de faire des suppositions basées sur la distribution de ce que vous pouvez et ne pouvez pas faire, car c'est de cette façon que réside la folie (voir aussi «Détection d'agent utilisateur»). Au lieu de cela, détectez si ce que vous voulez faire est pris en charge et comment cela se fait par la commande ou l'emplacement de fichier que vous souhaitez utiliser.

Par exemple, si vous souhaitez installer un paquet, vous pouvez détecter si vous êtes sur un système de type Debian ou un système de type RedHat en vérifiant l'existence de dpkg ou rpm (vérifiez d'abord dpkg, car les machines Debian peuvent avoir la commande rpm sur eux ...). Décidez de ce que vous devez faire en fonction de cela, pas seulement s'il s'agit d'un système Debian ou RedHat. De cette façon, vous prendrez automatiquement en charge toutes les distributions dérivées que vous n'avez pas explicitement programmées. Oh, et si votre package nécessite des dépendances spécifiques, testez-les également et faites savoir à l'utilisateur ce qu'elles manquent.

Un autre exemple est de jouer avec les interfaces réseau. Déterminez quoi faire en fonction de l'existence d'un fichier / etc / network / interfaces ou d'un répertoire / etc / sysconfig / network-scripts, et continuez à partir de là.

Oui, c'est plus de travail, mais à moins que vous ne vouliez refaire toutes les erreurs que les développeurs Web ont faites au cours de la dernière décennie ou plus, vous le ferez de manière intelligente dès le début.

womble
la source
1
(Développant cette réponse) La détection des fonctionnalités est préférable dans certaines situations, mais assurez-vous de ne jamais essayer de deviner la distribution à partir des fonctionnalités que vous détectez! Ne lisez pas mal la réponse et déterminez si la plate-forme est RedHat en fonction des fichiers contenus dans / etc. Si vous avez vraiment besoin du nom de la distribution, vérifiez lsb_release (ou / etc / redhat-release, etc.).
Nicholas Wilson
36

Il n'y a aucun moyen de distribution croisée. Toutefois:

  • Redhat et amis: /etc/redhat-releasetestez, vérifiez le contenu
  • Debian: tester /etc/debian_version, vérifier le contenu
  • Mandriva et ses amis: /etc/versiontestez, vérifiez le contenu
  • Slackware: tester /etc/slackware-version, vérifier le contenu

Etc. De manière générale, vérifiez /etc/*-releaseet /etc/*-version.


Edit: J'ai trouvé un vieux script bash (1+ ans) que je dois avoir bricolé au fil des ans (il a un journal CVS impressionnant datant de 6 ans.) Il pourrait ne plus fonctionner correctement tel quel et je peux ne vous embêtez pas à trouver des distributions installées pour tester, mais cela devrait vous fournir un bon point de départ. Cela fonctionne très bien sur CentOS, Fedora et Gentoo. gyaresu l'a testé avec succès sur 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
}

Notez que cela ne fonctionnera probablement correctement que dans Bash. Vous pouvez le réécrire pour d'autres coquilles.

Cela étant dit, vous voudrez peut-être tester les fonctionnalités, pas les distributions. Je n'utilise plus cela simplement parce que c'est devenu un fardeau de maintenance. Il est plus facile de s'appuyer sur des outils et des solutions de distribution croisée.


Conceptuellement, ce qu'il fait est, dans l'ordre:

  • Récupérez un fichier de type "fonction de script d'initialisation" connue. Ce sont spécifiques à la distribution. S'il n'existe pas, passez à la prochaine vérification de distribution.
  • Vérifiez l'existence d'une fonction spécifique, connue pour exister, souvent utilisée et peu susceptible d'être renommée à partir de ce script principal. Nous le faisons en utilisant le typeBash intégré. type -trenvoie functionsi ce symbole est une fonction. Nous ajoutons zzà la sortie de type -t 2>/dev/nullparce que si le nom n'est pas défini, la chaîne de sortie serait vide et nous obtiendrions une erreur de syntaxe concernant une main gauche manquante pour l' ==opérateur. Si le nom que nous venons de vérifier n'est pas une fonction, passez à la vérification de distribution suivante, sinon nous avons trouvé le type de distribution.
  • Enfin, faites écho au type de distribution pour que la sortie de fonction puisse être facilement utilisée dans un bloc case .. esac.

Modifier au cas où vous essayez de l'exécuter en tant que script simple: ce script est censé provenir ou être inclus à partir d'autres scripts. Il ne produit rien seul si vous l'exécutez tel quel. Pour le tester, sourcez-le puis appelez la fonction, par exemple:

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

à l'invite bash.


Edit: Veuillez noter que ce script ne nécessite pas de privilèges root. Je vous exhorte à ne pas l'exécuter en tant que root. Cela ne devrait rien nuire, mais ce n'est pas nécessaire.


Trouvé un lien vers une publication de liste de diffusion pertinente dans le journal CVS. Devrait être utile pour déballer les spaghettis de script init.

Mihai Limbăşan
la source
Je n'ai pas regardé pourquoi mais il revient pour demander Debian Lenny (5.0).
Gareth
gyaresu, avez-vous réellement invoqué la fonction get_distribution_type? J'ai édité le post pour clarifier (voir en bas.)
Mihai Limbăşan
@gyaresu: Si ce qui précède n'était pas le problème, pouvez-vous essayer de remplacer log_begin_msg dans la section Debian par log_warning_msg et réessayer? Il se peut que le nom de la fonction soit incorrect. Dans tous les cas, il aurait dû retourner "inconnu" si cette fonction n'était pas ici, mais quand même.
Mihai Limbăşan
@Mihai Doh! Désolé. N'a pas lu le script correctement. C'était tôt, pas de café. Mes excuses. gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth
@gyaresu: Merci! C'est bien, cela devrait aider jldugger à savoir que cela fonctionne aussi sur Debian :)
Mihai Limbăşan
17

Vous pouvez trouver la version du noyau en exécutant uname -a, trouver la version de distribution dépend de la distribution.

Sur Ubuntu et certains autres OS, vous pouvez exécuter lsb_release -aou lire / etc / lsb_release

Debian stocke la version dans / etc / debian_version

Adam Gibbins
la source
+1 pour lsb_release (fonctionne également sur les dérivés de Red Hat si le bon package est installé)
Josh Kelley
pour juste la description 'lsb_release -ds'.
flickerfly du
6

La plupart des distributions ont une méthode unique pour déterminer la distribution particulière.

Par exemple:

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

SUSE: /etc/SUSE-release

Il existe une norme connue sous le nom de Linux Standard Base ou LSB . Il définit qu'il devrait y avoir un fichier appelé / etc / lsb-release ou un programme appelé lsb_release qui fera écho des informations sur votre distribution Linux.

lsb_release -a
Mark Turner
la source
Et bien sûr, lsb_releasen'existe pas sur CentOS 6.
Justin
6
python -c 'import platform ; print platform.dist()[0]'

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

jkeogh
la source
Bonne idée. Je suggère d'utiliser python -c 'import platform; print(platform.dist()[0])', car de cette façon, cela fonctionne également si le python normal est par défaut python3.
heinrich5991
5

En plus des autres réponses: Si vous voulez juste analyser un fichier, la plupart des distributions personnalisent la connexion tty via / etc / issue, par exemple:

Bienvenue dans SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).

Et oui, je sais que ce n'est pas optimal. :)

Nœud
la source
Il peut être sous-optimal, mais il est au même endroit.
Brad Gilbert
4

facter est un outil pratique pour ce type de découverte, bien qu'il utilise probablement certaines des méthodes détaillées ci-dessus et nécessite Ruby.

Cawflands
la source
2

Tout ce que vous devez faire est de taper uname -asur votre shell préféré. Cela affichera le nom et la version du noyau.


la source
2

J'ai trouvé que cela fonctionne cat /etc/*release*presque toujours.

ibuys
la source
2

Je suis d'accord avec Mark, Adam et Mihai (je ne peux pas voter en raison d'une réputation insuffisante). Les solutions basées sur LSB et son FHS relatif fonctionneront avec la plupart des distributions et devraient continuer de fonctionner à l'avenir. LSB et FHS sont vos amis.

David J. Liszewski
la source
2

Vous pouvez également obtenir la version en

cat /proc/version

o / p:

Linux version 2.6.17-13mdv ([email protected]) (gcc version 4.1.2 20070302 (version préliminaire) (4.1.2-1mdv2007.1)) # 1 SMP ven 23 mars 19:03:31 UTC 2007

prasanna
la source
1

La version de Linux est une question difficile. Si nous l'examinons de près, nous avons la version du noyau que vous pouvez obtenir avec " uname -r". La version de distribution n'est généralement pas pertinente. Certaines distributions sont meilleures (distributions d'entreprise telles que Redhat Enterprise Linux). D'autres distributions comme Gentoo sont essentiellement des cibles mobiles qui n'ont aucune version sensible du tout. Si vous devez faire des choses en fonction de la version, jetez un œil aux principaux composants qui vous concernent:

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...
Paul de Vrieze
la source
1

Vous pouvez également consulter le menu Grub, vous donne généralement un tas d'informations sur la distribution / version :-)

Antoine Benkemoun
la source
-1

FusionInventory est un outil d'inventaire léger multiplateforme qui peut obtenir ces informations sur de nombreuses distributions Linux mais également sur BSD, Windows, MacOS X et autres unités.

S'ils sont disponibles, ils utilisent lsb_release(comme mentionné plusieurs fois ci-dessus), mais sinon, ils ont une liste très utile de fichiers et d'expressions régulières pour vérifier le nom et la version de la distribution: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .

Je recommanderais d'utiliser FusionInventory lui-même pour obtenir ces informations, plutôt que de réimplémenter vos propres scripts avec cette logique, car leur communauté maintiendra cette fonctionnalité à jour. Vous pouvez soit utiliser l'agent seul (il génère un fichier XML / JSON qui est facile à analyser) ou le coupler avec une solution plus large pour gérer les machines de votre réseau comme GLPI ou Rudder , selon vos besoins.

Jonathan Clarke
la source
Ce serait une bonne solution s'il n'avait pas de dépendances externes des modules Perl
Will Sheppard