Como posso obter o nome da distribuição e o número da versão em um script de shell simples?

172

Estou trabalhando em um script bash simples que deve ser capaz de rodar em distribuições Ubuntu e CentOS (suporte para Debian e Fedora / RHEL seria um plus) e eu preciso saber o nome e a versão da distribuição do script está em execução (para acionar ações específicas, por exemplo, a criação de repositórios). Até agora o que eu tenho é isso:

OS=$(awk '/DISTRIB_ID=/' /etc/*-release | sed 's/DISTRIB_ID=//' | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
VERSION=$(awk '/DISTRIB_RELEASE=/' /etc/*-release | sed 's/DISTRIB_RELEASE=//' | sed 's/[.]0/./')

if [ -z "$OS" ]; then
    OS=$(awk '{print $1}' /etc/*-release | tr '[:upper:]' '[:lower:]')
fi

if [ -z "$VERSION" ]; then
    VERSION=$(awk '{print $3}' /etc/*-release)
fi

echo $OS
echo $ARCH
echo $VERSION

Isso parece funcionar, retornando ubuntu ou centos (eu não tentei outros) como o nome do lançamento. No entanto, tenho a sensação de que deve haver uma maneira mais fácil e confiável de descobrir isso - isso é verdade?

Não funciona para o RedHat. O / etc / redhat-release contém: Redhat Linux Enterprise versão 5.5

Então, a versão não é a terceira palavra, é melhor você usar:

OS_MAJOR_VERSION='sed -rn 's/.*([0-9])\.[0-9].*//p' /etc/redhat-release'
OS_MINOR_VERSION='sed -rn 's/.*[0-9].([0-9]).*//p' /etc/redhat-release'
echo "RedHat/CentOS $OS_MAJOR_VERSION.$OS_MINOR_VERSION"
    
por Alix Axel 24.01.2011 / 06:00

18 respostas

163

Para obter OS e VER , o padrão mais recente parece ser /etc/os-release .  Antes disso, havia lsb_release e /etc/lsb-release . Antes disso, você precisava procurar arquivos diferentes para cada distribuição.

Veja o que eu sugiro

if [ -f /etc/os-release ]; then
    # freedesktop.org and systemd
    . /etc/os-release
    OS=$NAME
    VER=$VERSION_ID
elif type lsb_release >/dev/null 2>&1; then
    # linuxbase.org
    OS=$(lsb_release -si)
    VER=$(lsb_release -sr)
elif [ -f /etc/lsb-release ]; then
    # For some versions of Debian/Ubuntu without lsb_release command
    . /etc/lsb-release
    OS=$DISTRIB_ID
    VER=$DISTRIB_RELEASE
elif [ -f /etc/debian_version ]; then
    # Older Debian/Ubuntu/etc.
    OS=Debian
    VER=$(cat /etc/debian_version)
elif [ -f /etc/SuSe-release ]; then
    # Older SuSE/etc.
    ...
elif [ -f /etc/redhat-release ]; then
    # Older Red Hat, CentOS, etc.
    ...
else
    # Fall back to uname, e.g. "Linux <version>", also works for BSD, etc.
    OS=$(uname -s)
    VER=$(uname -r)
fi

Acho que uname para obter ARCH ainda é o melhor caminho. Mas o exemplo que você deu obviamente lida apenas com os sistemas da Intel. Eu chamaria BITS assim:

case $(uname -m) in
x86_64)
    BITS=64
    ;;
i*86)
    BITS=32
    ;;
*)
    BITS=?
    ;;
esac

Ou altere ARCH para as versões mais comuns, mas não ambíguas: x86 e x64 ou similar:

case $(uname -m) in
x86_64)
    ARCH=x64  # or AMD64 or Intel64 or whatever
    ;;
i*86)
    ARCH=x86  # or IA32 or Intel32 or whatever
    ;;
*)
    # leave ARCH as-is
    ;;
esac

mas é claro que depende de você.

    
por 24.01.2011 / 06:35
54

Eu vou com isso como um primeiro passo:

ls /etc/*release

Gentoo, RedHat, Arch & SuSE tem um arquivo chamado, por exemplo %código%. Parece ser popular, consulte este site sobre arquivos de lançamento .

Debian & O Ubuntu deve ter um /etc/gentoo-release que também contém informações de lançamento e aparecerá com o comando anterior.

Outra rápida é /etc/lsb-release . Se o kernel instalado for o kernel distro, você geralmente algumas vezes encontrará o nome lá.

    
por 29.03.2011 / 19:56
36

lsb_release -a . Funciona no Debian e acho que o Ubuntu, mas não tenho certeza sobre o resto. Normalmente deve existir em todas as distribuições GNU / Linux, uma vez que é relacionado ao LSB (Linux Standard Base).

    
por 29.03.2011 / 19:31
18

One-liner, fallbacks, uma linha de saída, sem erros.

lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om
    
por 22.11.2011 / 13:15
8
  1. lsb- * não está instalado / não existe em sistemas CentOS ou Debian básicos
  2. / proc / * não existe no OSX

Dê uma dica aos desenvolvedores de javascript. Não teste a versão, teste a capacidade. Não é bonito, mas funciona. Expanda conforme necessário.

function os_type
{
case 'uname' in
  Linux )
     LINUX=1
     which yum && { echo centos; return; }
     which zypper && { echo opensuse; return; }
     which apt-get && { echo debian; return; }
     ;;
  Darwin )
     DARWIN=1
     ;;
  * )
     # Handle AmgiaOS, CPM, and modified cable modems here.
     ;;
esac
}  
    
por 27.06.2012 / 11:02
8
python -c "import platform;print(platform.platform())"
    
por 12.04.2015 / 18:29
6

Em ordem de sucesso mais provável, estes:

cat /etc/*version
cat /proc/version #linprocfs/version for FreeBSD when "linux" enabled
cat /etc/*release
uname -rv

cobre a maioria dos casos (AFAIK): Debian, Ubuntu, Slackware, Suse, Redhat, Gentoo, * BSD e talvez outros.

    
por 30.03.2011 / 02:45
5

Para a maioria dos sistemas operacionais Linux modernos, o arquivo /etc/os-release está realmente se tornando padrão e está sendo incluído na maioria dos sistemas operacionais. Então, dentro do seu script Bash você pode simplesmente incluir o arquivo, e você terá acesso a todas as variáveis descritas aqui (por exemplo: NAME, VERSION, ...)

Então, estou usando isso no meu script Bash:

if [ -f /etc/os-release ]
then
        . /etc/os-release
else
        echo "ERROR: I need the file /etc/os-release to determine what my distribution is..."
        # If you want, you can include older or distribution specific files here...
        exit
fi
    
por 17.04.2014 / 16:17
3

Se o arquivo /etc/debian_version existir, a distribuição é Debian, ou um derivado Debian. Este arquivo pode ter um número de lançamento; na minha máquina, ela é atualmente 6.0.1 . Se está testando ou instável, pode dizer testing / unstable, ou pode ter o número da próxima versão. Minha impressão é que, pelo menos no Ubuntu, esse arquivo está sempre testando / instável, e que eles não colocam o número do release nele, mas alguém pode me corrigir se eu estiver errado.

O Fedora (versões recentes, pelo menos) tem um arquivo similar, chamado /etc/fedora-release .

    
por 29.03.2011 / 18:10
2

Se você não puder ou não quiser usar o arquivo de versão do LSB (devido às dependências que o pacote traz), você pode procurar os arquivos de lançamento específicos da distribuição. O Bcfg2 tem uma sonda para a distro que você pode usar: link

    
por 24.01.2011 / 15:28
1

2 maneiras de muitos:

1) use

lsb_release -a

Eu testei no CentOS 5.5 e no Ubuntu 10.04

a saída para o CentOS é:

LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch 
Distributor ID: CentOS
Description:    CentOS release 5.5 (Final)
Release:        5.5
Codename:       Final

e para o Ubuntu é:

LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description:    CentOS release 5.5 (Final)
Release:        5.5
Codename:       Final

2) digite o seguinte comando:

cat /etc/*-release

Eu testei no CentOS 5.5 e no Ubuntu 10.04, e funciona bem.

    
por 28.04.2012 / 16:49
0

Este script funciona no Debian, (pode precisar de algum ajuste no Ubuntu)

#!/usr/bin/env bash

echo "Finding Debian/ Ubuntu Codename..."

CODENAME='cat /etc/*-release | grep "VERSION="'
CODENAME=${CODENAME##*\(}
CODENAME=${CODENAME%%\)*}

echo "$CODENAME"
# => saucy, precise, lucid, wheezy, squeeze
    
por 17.11.2013 / 10:26
0

Aqui está a minha versão simples chech_distro. ^^;

#!/usr/bin/env bash
check_distro2(){
    if [[ -e /etc/redhat-release ]]
    then
      DISTRO=$(cat /etc/redhat-release)
    elif [[ -e /usr/bin/lsb_release ]]
    then
      DISTRO=$(lsb_release -d | awk -F ':' '{print $2}')
    elif [[ -e /etc/issue ]]
    then
      DISTRO=$(cat /etc/issue)
    else
      DISTRO=$(cat /proc/version)
    fi
    }

    check_distro2
    echo $DISTRO
    
por 01.07.2015 / 00:04
0

Sem versão, apenas dist:

cat /etc/issue | head -n +1 | awk '{print $1}'
    
por 20.07.2015 / 07:30
0

Isso foi testado no Ubuntu 14 e no CentOS 7

cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $1}'
    
por 23.11.2015 / 02:08
0

Eu acho um bom script aqui que funciona para a maioria dos distintos linux comuns:

#! /bin/bash
# return an awkable string consisting of
#    unix OS type, or
#    Linux dist, or
#    a long guess (based on /proc), or
#    no clue

giveUp () {
   echo "Unknown"
   exit 0
}

# keep this easily awkable, prepending an initial clue
versionGuess () {
   if [ -e /proc/version ]; then
      echo -n "Unsure "
      cat /proc/version
      exit 0
   fi
   return 1
}

# if we have ignition, print and exit
gotDist () {
   [ -n "$1" ] && echo "$1" && exit 0
}

# we are only interested in a single word "dist" here
# various malformations can occur; admin will have to code appropately based on output
linuxRelease () {
   if [ -r /etc/lsb-release ]; then
      dist=$(grep 'DISTRIB_ID' /etc/lsb-release | sed 's/DISTRIB_ID=//' | head -1)
      gotDist "$dist"
   fi

   dist=$(find /etc/ -maxdepth 1 -name '*release' 2> /dev/null | sed 's/\/etc\///' | sed 's/-release//' | head -1)
   gotDist "$dist"

   dist=$(find /etc/ -maxdepth 1 -name '*version' 2> /dev/null | sed 's/\/etc\///' | sed 's/-version//' | head -1)
   gotDist "$dist"

   return 1
}

# start with uname and branch the decision from there
dist=$(uname -s 2> /dev/null)
if [ "$dist" = "Linux" ]; then
   linuxRelease
   versionGuess
   giveUp
elif [ -n "$dist" ]; then
   echo "$dist"
   exit 0
else
   versionGuess
   giveUp
fi

# we shouldn't get here
giveUp
# done
    
por 27.10.2016 / 10:53
0

Eu uso o utilitário de script screenfetch :

    
por 10.12.2018 / 11:28
-3

Este comando funciona para distribuições baseadas em Debian e baseadas em Redhat: Usando o filtro tr , você converte o documento para o formato de uma palavra por linha e depois conta a primeira linha que contém o nome da distribuição.

tr -s ' 1' '2' < /etc/issue | head -n 1
    
por 18.12.2014 / 17:11

Tags