À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?
À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?
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.
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/*-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.
#!/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
type
Bash embutido.type -t
retornafunction
se esse símbolo é uma função. Anexamoszz
a saída detype -t 2>/dev/null
porque, 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:
source /path/to/this/script.sh
get_distribution_type
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.
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_release
O Debian armazena a versão em / etc / debian_version
A maioria das distros possui um método único para determinar a distribuição específica.
Por exemplo:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
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.
lsb_release -a
lsb_release
é claro, não existe no CentOS 6. #
python -c 'import platform ; print platform.dist()[0]'
código: http://hg.python.org/cpython/file/2.7/Lib/platform.py
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:
Bem-vindo ao SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).
E sim, eu sei que é subótimo. :)
Tudo que você precisa fazer é digitar uname -a
no seu shell favorito. Isso imprimirá o nome e a versão do kernel.
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ê:
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...
Você também pode verificar o menu Grub, geralmente fornece várias informações sobre a distribuição / versão :-)
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.