¿Cómo puedo saber qué versión de Linux se está ejecutando?

29

A veces, sus scripts deben comportarse de manera diferente en diferentes Linux. ¿Cómo puedo determinar en qué versión de Linux se ejecuta un script?

jldugger
fuente
1
Por versión, ¿te refieres a la versión del kernel? Que distribucion La versión de la distribución?
Chris Upchurch
2
Estoy seguro de que jldugger quiere averiguar qué familia de distribución está ejecutando el sistema. Es poco probable que un script se vea afectado por la versión del kernel a menos que dependa de algunas cosas / sys o / proc, e incluso entonces es más fácil asumirlo en función de la distribución que del kernel.
Mihai Limbăşan

Respuestas:

27

No intente hacer suposiciones basadas en la distribución en cuanto a lo que puede y no puede hacer, ya que de ese modo se encuentra la locura (consulte también "Detección de agente de usuario"). En su lugar, detecta si lo que quieres hacer es compatible y cómo lo hace cualquier comando o ubicación de archivo que quieras usar.

Por ejemplo, si desea instalar un paquete, puede detectar si está en un sistema similar a Debian o un sistema similar a RedHat verificando la existencia de dpkg o rpm (compruebe primero dpkg, porque las máquinas Debian pueden tener el comando rpm en ellos ...). Tome su decisión sobre qué hacer basándose en eso, no solo en si es un sistema Debian o RedHat. De esta forma, admitirá automáticamente cualquier distribución derivada que no haya programado explícitamente. Ah, y si su paquete requiere dependencias específicas, pruebe también esas y deje que el usuario sepa lo que falta.

Otro ejemplo es jugar con las interfaces de red. Determine qué hacer en función de si hay un archivo / etc / network / interfaces o un directorio / etc / sysconfig / network-scripts, y vaya desde allí.

Sí, es más trabajo, pero a menos que desee rehacer todos los errores que los desarrolladores web han cometido en la última década o más, lo hará de manera inteligente desde el principio.

womble
fuente
1
(Ampliando esta respuesta) La detección de funciones es preferible en algunas situaciones, ¡pero asegúrese de nunca intentar adivinar la distribución de las funciones que detecta! No lea mal la respuesta y averigüe si la plataforma es RedHat en función de los archivos que se encuentran en / etc. Si realmente necesita el nombre de la distribución, marque lsb_release (o / etc / redhat-release, etc.).
Nicholas Wilson
36

No hay forma de distribución cruzada. Sin embargo:

  • Redhat y amigos: prueba /etc/redhat-release, verifica el contenido
  • Debian: prueba /etc/debian_version, verifica el contenido
  • Mandriva y sus amigos: prueba para /etc/versionverificar el contenido
  • Slackware: prueba /etc/slackware-version, verifica el contenido

Etc. En términos generales, verifique /etc/*-releasey /etc/*-version.


Editar: Encontré un viejo script de bash mío (1+ años) por ahí que debo haber improvisado a lo largo de los años (tiene un impresionante registro de CVS que data de hace 6 años). Puede que ya no funcione correctamente tal como está y puedo No se moleste en encontrar distribuciones instaladas para probar, pero debería proporcionarle un buen punto de partida. Funciona bien en CentOS, Fedora y Gentoo. gyaresu lo probó con éxito en 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
}

Tenga en cuenta que esto probablemente solo funcionará correctamente en Bash. Podrías reescribirlo para otros proyectiles.

Dicho esto, es posible que desee probar las características, no las distribuciones. Ya no estoy usando esto simplemente porque se convirtió en una carga de mantenimiento. Es más fácil confiar en herramientas y soluciones de distribución cruzada.


Conceptualmente, lo que hace es, en orden:

  • Extraiga un tipo de archivo conocido, "función de secuencia de comandos de inicio común". Esos son específicos de distribución. Si no existe, pase a la siguiente verificación de distribución.
  • Verifique la existencia de una función específica, conocida por existir, de uso frecuente y poco probable que cambie de nombre a partir de ese script central. Hacemos eso usando el typeBash incorporado. type -tdevuelve functionsi ese símbolo es una función. Anteponemos zzla salida de type -t 2>/dev/nullporque si el nombre no está definido, la cadena de salida estaría vacía y obtendríamos un error de sintaxis sobre una mano izquierda faltante para el ==operador. Si el nombre que acabamos de verificar no es una función, salte a la siguiente verificación de distribución, de lo contrario, encontramos el tipo de distribución.
  • Finalmente, repita el tipo de distribución para que la salida de la función se pueda usar fácilmente en un caso ... ese bloque.

Edite en caso de que esté tratando de ejecutar esto como un script directo: se supone que este script debe obtenerse o incluirse de otros scripts. No genera nada por sí solo si lo ejecuta tal cual. Para probarlo, búsquelo y luego invoque la función, por ejemplo:

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

en el indicador de bash.


Editar: tenga en cuenta que este script no requiere privilegios de root. Te insto a que no lo ejecutes como root. No debería dañar nada, pero no hay necesidad.


Encontré un enlace a una publicación de lista de correo relevante en el registro de CVS. Debería ser útil para desenvolver los espaguetis de script de inicio.

Mihai Limbăşan
fuente
No he visto por qué, pero vuelve a aparecer en Debian Lenny (5.0).
Gareth
gyaresu, ¿has invocado realmente la función get_distribution_type? He editado la publicación para aclarar (ver al final)
Mihai Limbăşan
@ gyaresu: Si lo anterior no fue el problema, ¿puede intentar reemplazar log_begin_msg en la sección de Debian con log_warning_msg y volver a intentarlo? Podría haber obtenido el nombre de la función incorrecto. En cualquier caso, debería haber devuelto "desconocido" si esa función no era ahora, pero aún así.
Mihai Limbăşan
@Mihai Doh! Lo siento. No leí el guión correctamente. Era temprano, no había café. Mis disculpas gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth
@ gyaresu: ¡Gracias! Eso es bueno, debería ayudar jldugger sepa que funciona en Debian, así :)
Mihai Limbăşan
17

Puede encontrar la versión del kernel ejecutando uname -a, encontrar la versión de distribución depende de la distribución.

En Ubuntu y otros sistemas operativos, puede ejecutar lsb_release -ao leer / etc / lsb_release

Debian almacena la versión en / etc / debian_version

Adam Gibbins
fuente
+1 para lsb_release (también funciona en derivados de Red Hat si está instalado el paquete correcto)
Josh Kelley
solo por la descripción 'lsb_release -ds'.
flickerfly
6

La mayoría de las distribuciones tienen un método único para determinar la distribución particular.

Por ejemplo:

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

SUSE: /etc/SUSE-release

Existe un estándar conocido como Linux Standard Base o LSB . Define que debe haber un archivo llamado / etc / lsb-release o un programa llamado lsb_release que hará eco de la información sobre su distribución de Linux.

lsb_release -a
Mark Turner
fuente
Y, por supuesto, lsb_releaseno existe en CentOS 6.
Justin
6
python -c 'import platform ; print platform.dist()[0]'

código: http://hg.python.org/cpython/file/2.7/Lib/platform.py

jkeogh
fuente
Gran idea. Sugeriría usarlo python -c 'import platform; print(platform.dist()[0])', porque de esa manera también funciona si el pitón normal predeterminado es python3.
heinrich5991
5

Además de las otras respuestas: si solo desea analizar un archivo, la mayoría de las distribuciones personalizan el inicio de sesión de tty a través de / etc / issue, por ejemplo:

Bienvenido a SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).

Y sí, sé que es subóptimo. :)

Nodo
fuente
Puede ser subóptimo, pero está en el mismo lugar.
Brad Gilbert
4

facter es una herramienta útil para este tipo de descubrimiento, aunque probablemente utiliza algunos de los métodos detallados anteriormente y requiere Ruby.

Cawflands
fuente
2

Todo lo que necesita hacer es escribir uname -aen su shell favorito. Eso imprimirá el nombre y la versión del núcleo.


fuente
2

He descubierto que cat /etc/*release*casi siempre funciona.

ibuys
fuente
2

Estoy de acuerdo con Mark, Adam y Mihai (no puedo votar debido a una reputación insuficiente). Las soluciones basadas en LSB y su relativa FHS funcionarán con la mayoría de las distribuciones y es probable que continúen funcionando en el futuro. LSB y FHS son tus amigos.

David J. Liszewski
fuente
2

También puede obtener la versión por

cat /proc/version

o / p:

Linux versión 2.6.17-13mdv ([email protected]) (gcc versión 4.1.2 20070302 (prelanzamiento) (4.1.2-1mdv2007.1)) # 1 SMP viernes 23 de marzo 19:03:31 UTC 2007

prasanna
fuente
1

La versión de Linux es una pregunta difícil. Si lo miramos de forma limitada, tenemos la versión del núcleo que puede obtener con " uname -r". La versión de distribución es principalmente irrelevante. Algunas distribuciones son mejores (distribuciones empresariales como Redhat Enterprise Linux). Otras distribuciones como Gentoo son básicamente objetivos móviles que no tienen una versión sensible. Si necesita hacer cosas según la versión, eche un vistazo a los componentes principales que son relevantes para usted:

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
fuente
1

También puede consultar el menú Grub, que generalmente le ofrece un montón de información de distribución / versión :-)

Antoine Benkemoun
fuente
-1

FusionInventory es una herramienta de inventario ligera multiplataforma que puede obtener esta información en muchas distribuciones de Linux, pero también en BSD, Windows, MacOS X y otros dispositivos.

Si están disponibles, usan lsb_release(como se mencionó varias veces anteriormente), pero si no tienen una lista muy útil de archivos y expresiones regulares para verificar el nombre y la versión de la distribución: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .

Recomendaría usar FusionInventory para obtener esta información, en lugar de volver a implementar sus propios scripts con esta lógica, ya que su comunidad mantendrá esta funcionalidad actualizada. Puede usar el agente por sí mismo (genera un archivo XML / JSON que es fácil de analizar) o acoplarlo con una solución más amplia para administrar las máquinas en su red como GLPI o Rudder , según sus necesidades.

Jonathan Clarke
fuente
Esta sería una buena solución si no tuviera dependencias externas de los módulos de Perl
Will Sheppard