Como descubro qual versão do Linux está sendo executada?
29
Às vezes, seus scripts precisam se comportar de maneira diferente em diferentes Linuxs. Como posso determinar em qual versão do Linux um script está sendo executado?
Por versão, você quer dizer a versão do kernel? Que distribuição? A versão distro?
Chris Upchurch #
2
Tenho certeza que o jldugger deseja descobrir qual família de distribuição o sistema está executando. É improvável que um script seja afetado pela versão do kernel, a menos que dependa de algumas coisas / sys ou / proc - e mesmo assim geralmente é mais fácil assumir com base na distribuição do que no kernel.
Mihai Limbăşan
Respostas:
27
Não tente fazer suposições com base na distribuição do que você pode ou não fazer, pois dessa maneira está a loucura (consulte também "Detecção do agente do usuário"). Em vez disso, detecte se o que você deseja fazer é suportado e como é feito por qualquer comando ou local do arquivo que você deseja usar.
Por exemplo, se você deseja instalar um pacote, pode detectar se está em um sistema semelhante ao Debian ou no sistema RedHat, verificando a existência de dpkg ou rpm (verifique primeiro o dpkg, porque as máquinas Debian podem ter o comando rpm neles ...). Decida o que fazer com base nisso, não apenas se é um sistema Debian ou RedHat. Dessa forma, você suportará automaticamente todas as distribuições derivadas nas quais você não programou explicitamente. Ah, e se o seu pacote exigir dependências específicas, teste-as também e informe ao usuário o que está faltando.
Outro exemplo é mexer com interfaces de rede. Elabore o que fazer com base no fato de haver um arquivo / etc / network / interfaces ou um diretório / etc / sysconfig / network-scripts e siga a partir daí.
Sim, é mais trabalho, mas, a menos que você queira refazer todos os erros que os desenvolvedores da Web cometeram na última década ou mais, você o fará da maneira mais inteligente desde o início.
(Expandindo esta resposta) A detecção de recursos é preferível em algumas situações, mas certifique-se de nunca tentar adivinhar a distribuição a partir dos recursos que você detectar! Não interprete mal a resposta e verifique se a plataforma é RedHat com base em quais arquivos estão no / etc. Se você realmente precisa do nome da distribuição, verifique lsb_release (ou / etc / redhat-release, e assim por diante).
Nicholas Wilson
36
Não há maneira de distribuição cruzada. Contudo:
Redhat e amigos: teste /etc/redhat-release, verifique o conteúdo
Debian: Teste /etc/debian_version, verifique o conteúdo
Mandriva e amigos: teste /etc/version, verifique o conteúdo
Slackware: Teste /etc/slackware-version, verifique o conteúdo
Etc. De um modo geral, verifique /etc/*-releasee /etc/*-version.
Edit: Encontrei um antigo script bash meu (1+ anos) por aí que eu devo ter misturado ao longo dos anos (ele tem um impressionante registro CVS que remonta a 6 anos). Pode não funcionar mais corretamente como está e não se preocupe em encontrar distribuições instaladas para testar, mas deve fornecer um bom ponto de partida. Funciona bem no CentOS, Fedora e Gentoo. O gyaresu testou com sucesso no 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
}
Observe que isso provavelmente só funcionará corretamente no Bash. Você pode reescrevê-lo para outras conchas.
Dito isto, você pode querer testar recursos, não distribuições. Não estou mais usando isso simplesmente porque se tornou um fardo de manutenção. É mais fácil confiar em ferramentas e soluções de distribuição cruzada.
Conceitualmente, o que faz é, em ordem:
Pegue um tipo conhecido de arquivo "common init function function". Esses são específicos da distribuição. Se não existir, pule para a próxima verificação de distribuição.
Verifique a existência de uma função específica, conhecida por existir, frequentemente usada e improvável de ser renomeada nesse script principal. Fazemos isso usando o typeBash embutido. type -tretorna functionse esse símbolo é uma função. Anexamos zza saída de type -t 2>/dev/nullporque, se o nome não for definido, a string de saída estará vazia e obteremos um erro de sintaxe sobre a falta de uma mão esquerda para o ==operador. Se o nome que acabamos de verificar não for uma função, pule para a próxima verificação de distribuição, caso contrário, encontramos o tipo de distribuição.
Por fim, faça eco do tipo de distribuição para que a saída da função possa ser facilmente usada em um caso .. bloco esac.
Edite caso esteja tentando executar isso como um script direto: esse script deve ser obtido ou incluído em outros scripts. Ele não produz nada por si só, se você o executar como está. Para testá-lo, obtenha-o e, em seguida, chame a função, por exemplo:
Editar: Observe que este script não requer privilégios de root. Peço que você não o execute como root. Não deve prejudicar nada, mas não há necessidade.
Encontrou um link para uma postagem relevante na lista de discussão no log do CVS. Deve ser útil para desembrulhar o espaguete de script init.
Eu não olhei o porquê, mas ele retorna ao prompt do Debian Lenny (5.0).
530 Gareth
gyaresu, você realmente invocou a função get_distribution_type? Eu editei o post para esclarecer (ver na parte inferior.)
Mihai Limbăşan
@gyaresu: Se o problema acima não foi o problema, você pode substituir o log_begin_msg na seção Debian por log_warning_msg e tentar novamente? Pode ter errado o nome da função. De qualquer forma, ele deveria ter retornado "desconhecido" se essa função não fosse antiga, mas ainda assim.
Mihai Limbăşan
@Mihai Doh! Desculpe. Não leu o script corretamente. Era cedo, sem café. Peço desculpas. gyaresu @ debian: ~ / bin $ server_version.sh de origem gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth
@gyaresu: Obrigado! Isso é bom, deve ajudar jldugger saber que ele funciona em Debian assim :)
Mihai Limbăşan
17
Você pode encontrar a versão do kernel executando uname -a, localizando a versão da distribuição depende da distribuição.
No Ubuntu e em algum outro sistema operacional, você pode executar lsb_release -aou ler / etc / lsb_release
O Debian armazena a versão em / etc / debian_version
Existe um padrão conhecido como Linux Standard Base ou LSB . Ele define que deve haver um arquivo chamado / etc / lsb-release ou um programa chamado lsb_release que retornará informações sobre sua distribuição Linux.
Boa ideia. Eu sugeriria o uso python -c 'import platform; print(platform.dist()[0])', porque dessa maneira também funciona se o python normal usar como padrão python3.
precisa
5
Além das outras respostas: Se você deseja apenas analisar um arquivo, a maioria das distros personaliza o login tty via / etc / issue, por exemplo:
Bem-vindo ao SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).
Concordo com Mark, Adam e Mihai (não posso votar devido à reputação insuficiente). As soluções baseadas no LSB e na sua ESF relativa funcionarão com a maioria das distribuições e provavelmente continuarão trabalhando no futuro. LSB e FHS são seus amigos.
A versão do linux é uma pergunta difícil. Se olharmos de perto, temos a versão do kernel que você pode obter com " uname -r". A versão de distribuição é principalmente irrelevante. Algumas distribuições são melhores (distribuições corporativas, como o Redhat Enterprise Linux). Outras distribuições como o Gentoo são basicamente alvos móveis que não possuem nenhuma versão sensata. Se você precisar fazer as coisas com base na versão, dê uma olhada nos principais componentes que são relevantes para você:
O FusionInventory é uma ferramenta de inventário leve multiplataforma que pode obter essas informações em muitas distribuições Linux, mas também em BSDs, Windows, MacOS X e outros departamentos.
Eu recomendaria usar o próprio FusionInventory para obter essas informações, em vez de reimplementar seus próprios scripts com essa lógica, pois a comunidade deles manterá essa funcionalidade atualizada. Você pode usar o agente por si próprio (ele gera um arquivo XML / JSON que é fácil de analisar) ou associá-lo a uma solução mais ampla para gerenciar as máquinas em sua rede como GLPI ou Rudder , dependendo de suas necessidades.
Respostas:
Não tente fazer suposições com base na distribuição do que você pode ou não fazer, pois dessa maneira está a loucura (consulte também "Detecção do agente do usuário"). Em vez disso, detecte se o que você deseja fazer é suportado e como é feito por qualquer comando ou local do arquivo que você deseja usar.
Por exemplo, se você deseja instalar um pacote, pode detectar se está em um sistema semelhante ao Debian ou no sistema RedHat, verificando a existência de dpkg ou rpm (verifique primeiro o dpkg, porque as máquinas Debian podem ter o comando rpm neles ...). Decida o que fazer com base nisso, não apenas se é um sistema Debian ou RedHat. Dessa forma, você suportará automaticamente todas as distribuições derivadas nas quais você não programou explicitamente. Ah, e se o seu pacote exigir dependências específicas, teste-as também e informe ao usuário o que está faltando.
Outro exemplo é mexer com interfaces de rede. Elabore o que fazer com base no fato de haver um arquivo / etc / network / interfaces ou um diretório / etc / sysconfig / network-scripts e siga a partir daí.
Sim, é mais trabalho, mas, a menos que você queira refazer todos os erros que os desenvolvedores da Web cometeram na última década ou mais, você o fará da maneira mais inteligente desde o início.
fonte
Não há maneira de distribuição cruzada. Contudo:
Etc. De um modo geral, verifique
/etc/*-release
e/etc/*-version
.Edit: Encontrei um antigo script bash meu (1+ anos) por aí que eu devo ter misturado ao longo dos anos (ele tem um impressionante registro CVS que remonta a 6 anos). Pode não funcionar mais corretamente como está e não se preocupe em encontrar distribuições instaladas para testar, mas deve fornecer um bom ponto de partida. Funciona bem no CentOS, Fedora e Gentoo. O gyaresu testou com sucesso no Debian Lenny.
Observe que isso provavelmente só funcionará corretamente no Bash. Você pode reescrevê-lo para outras conchas.
Dito isto, você pode querer testar recursos, não distribuições. Não estou mais usando isso simplesmente porque se tornou um fardo de manutenção. É mais fácil confiar em ferramentas e soluções de distribuição cruzada.
Conceitualmente, o que faz é, em ordem:
Edite caso esteja tentando executar isso como um script direto: esse script deve ser obtido ou incluído em outros scripts. Ele não produz nada por si só, se você o executar como está. Para testá-lo, obtenha-o e, em seguida, chame a função, por exemplo:
no prompt do bash.
Editar: Observe que este script não requer privilégios de root. Peço que você não o execute como root. Não deve prejudicar nada, mas não há necessidade.
Encontrou um link para uma postagem relevante na lista de discussão no log do CVS. Deve ser útil para desembrulhar o espaguete de script init.
fonte
Você pode encontrar a versão do kernel executando
uname -a
, localizando a versão da distribuição depende da distribuição.No Ubuntu e em algum outro sistema operacional, você pode executar
lsb_release -a
ou ler / etc / lsb_releaseO Debian armazena a versão em / etc / debian_version
fonte
A maioria das distros possui um método único para determinar a distribuição específica.
Por exemplo:
Existe um padrão conhecido como Linux Standard Base ou LSB . Ele define que deve haver um arquivo chamado / etc / lsb-release ou um programa chamado lsb_release que retornará informações sobre sua distribuição Linux.
fonte
lsb_release
é claro, não existe no CentOS 6. #código: http://hg.python.org/cpython/file/2.7/Lib/platform.py
fonte
python -c 'import platform; print(platform.dist()[0])'
, porque dessa maneira também funciona se o python normal usar como padrão python3.Além das outras respostas: Se você deseja apenas analisar um arquivo, a maioria das distros personaliza o login tty via / etc / issue, por exemplo:
E sim, eu sei que é subótimo. :)
fonte
O facter é uma ferramenta útil para esse tipo de descoberta, embora provavelmente use alguns dos métodos detalhados acima e exija Ruby.
fonte
Tudo que você precisa fazer é digitar
uname -a
no seu shell favorito. Isso imprimirá o nome e a versão do kernel.fonte
Eu descobri que
cat /etc/*release*
quase sempre funciona.fonte
Concordo com Mark, Adam e Mihai (não posso votar devido à reputação insuficiente). As soluções baseadas no LSB e na sua ESF relativa funcionarão com a maioria das distribuições e provavelmente continuarão trabalhando no futuro. LSB e FHS são seus amigos.
fonte
Você também pode obter a versão
o / p:
fonte
A versão do linux é uma pergunta difícil. Se olharmos de perto, temos a versão do kernel que você pode obter com "
uname -r
". A versão de distribuição é principalmente irrelevante. Algumas distribuições são melhores (distribuições corporativas, como o Redhat Enterprise Linux). Outras distribuições como o Gentoo são basicamente alvos móveis que não possuem nenhuma versão sensata. Se você precisar fazer as coisas com base na versão, dê uma olhada nos principais componentes que são relevantes para você:fonte
Você também pode verificar o menu Grub, geralmente fornece várias informações sobre a distribuição / versão :-)
fonte
O FusionInventory é uma ferramenta de inventário leve multiplataforma que pode obter essas informações em muitas distribuições Linux, mas também em BSDs, Windows, MacOS X e outros departamentos.
Se disponíveis, eles usam
lsb_release
(como mencionado algumas vezes acima), mas se não tiverem uma lista muito útil de arquivos e expressões regulares para verificar o nome e a versão da distribuição: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .Eu recomendaria usar o próprio FusionInventory para obter essas informações, em vez de reimplementar seus próprios scripts com essa lógica, pois a comunidade deles manterá essa funcionalidade atualizada. Você pode usar o agente por si próprio (ele gera um arquivo XML / JSON que é fácil de analisar) ou associá-lo a uma solução mais ampla para gerenciar as máquinas em sua rede como GLPI ou Rudder , dependendo de suas necessidades.
fonte