Isso pode ter mais a ver com a detecção de sistemas operacionais, mas eu preciso especificamente do sistema init atualmente em uso no sistema.
O Fedora 15 e o Ubuntu agora usam o systemd, o Ubuntu costumava usar o Upstart (há muito tempo padrão até 15.04), enquanto outros usam variações do System V.
Eu tenho um aplicativo que estou escrevendo para ser um daemon de plataforma cruzada. Os scripts init estão sendo gerados dinamicamente com base em parâmetros que podem ser transmitidos no configure.
O que eu gostaria de fazer é gerar apenas o script para o sistema init específico que eles estão usando. Dessa forma, o script de instalação pode ser executado razoavelmente sem parâmetros como root e o daemon pode ser "instalado" automaticamente.
Isto é o que eu vim com:
- Procure systemd, upstart, etc em / bin
- Compare / proc / 1 / comm ao systemd, upstart, etc
- Pergunte ao usuário
Qual seria a melhor maneira multiplataforma de fazer isso?
Tipo de relação, posso depender do bash para estar na maioria dos * nix ou depende da distribuição / SO?
Plataformas alvo:
- Mac OS
- Linux (todas as distribuições)
- BSD (todas as versões)
- Solaris, Minix e outros * nix
fonte
ps -p 1 -o command
(imprime o caminho para o atualinit
). No Arch Linux e Fedora (IIRC), é um link simbólico para osystemd
binário (provavelmente o mesmo em todos ossystemd
sistemas). Ativadoupstart
,init --help
imprime informações de uso e, na minha caixa,upstart
é mencionado onde diz para quem enviar e-mail. No FreeBSD (sysV), isso retornará um erro. Pode haver pistas semelhantes em outros sistemas, mas desde que fiz essa pergunta, decidi criá-las para todas as plataformas e criar pacotes separados para cada uma.sudo lsof -a -p 1 -d txt
pode dar resultados ainda mais exatos.ps
pode imprimir um nome arbitrário, enquanto quelsof
você obterá o caminho real do executável. (Veja minha pergunta unix.stackexchange.com/questions/102453/… )Respostas:
Para a segunda pergunta, a resposta é não e você deve dar uma olhada em Recursos para programação de shell portátil .
Quanto à primeira parte - primeiro de tudo, você certamente precisa ter cuidado. Eu diria que execute vários testes para ter certeza - porque o fato de alguém ter o systemd (por exemplo) instalado, não significa que ele seja realmente usado como padrão
init
. Além disso, a observação/proc/1/comm
pode ser enganosa, porque algumas instalações de vários programas init podem criar automaticamente/sbin/init
um link simbólico ou mesmo uma versão renomeada de seu programa principal.Talvez a coisa mais útil seja olhar para o tipo de script init - porque é isso que você realmente criará, não importa o que os execute.
Como uma observação lateral, você também pode dar uma olhada no OpenRC, que visa fornecer uma estrutura de scripts init que seja compatível com os sistemas Linux e BSD.
fonte
/etc/init
, como o systemd os coloca/etc/systemd
. Para que meu script os resulte, pode demorar um pouco. Ah, e obrigado pelo link BTW para programação de shell portátil./etc/rc.d/
ou/etc/init.d/
). E você deve ajustar corretamente seu programa no momento da instalação para utilizar a estrutura usada no sistema fornecido.Eu mesmo pisei nesse problema e decidi fazer alguns testes. Concordo plenamente com a resposta de que cada pacote deve ser distribuído separadamente, mas às vezes há questões práticas que o impedem (pelo menos mão-de-obra).
Portanto, para aqueles que desejam "detectar automaticamente", eis o que eu descobri em um conjunto limitado de distribuições (mais abaixo):
Você pode saber desde o início:
Você pode dizer ao systemd em:
Você pode dizer ao sys-v init em:
Aqui estão minhas experiências com a seguinte linha de comando:
em instâncias ec2 (estou incluindo o ID da AMI nos EUA):
Só para esclarecer: não estou afirmando que isso é infalível! , quase certamente não é. Observe também que, por conveniência, uso correspondências bash regexp, que não estão disponíveis em todos os lugares. O acima é bom o suficiente para mim agora. No entanto, se você encontrar uma distro em que ela falhar, informe-me e tentarei corrigi-la se houver uma AMI EC2 que reproduza o problema ...
fonte
/run/systemd/system
existe.launchd
, o sistema init no macOS:[[ $(ps 1) =~ 'launchd' ]] && echo yes || echo no
testado em um MacBookPro, macOS Sierra Versão 10.12if [ -h /sbin/init -a $(readlink /sbin/init | grep busybox | wc -l) -gt 0 ]; then echo yes; else echo no; fi
Usando processos
Observando a saída de alguns
ps
comandos que podem detectar as várias versões dosystemd
&upstart
, que podem ser criadas da seguinte maneira:subir na vida
systemd
Prestar atenção ao nome do processo PID # 1 também pode potencialmente esclarecer qual sistema init está sendo usado. No Fedora 19 (que usa
systemd
, por exemplo:Observe que não é
init
. No Ubuntu com Upstart ainda está/sbin/init
.NOTA: Mas use isso com um pouco de cautela. Não há nada definido que diga que um sistema init específico que está sendo usado em uma determinada distribuição deve ter
systemd
como o PID # 1.genérico
Veja os processos com o ppid 1 (filhos do processo init). (Alguns dos) nomes de processos filhos podem apontar para o sistema init em uso.
O sistema de arquivos
Se você interrogar o
init
executável, também poderá obter algumas informações. Simplesmente analisando a--version
saída. Por exemplo:subir na vida
systemd
NOTA: O fato de
init
não estar em sua localização padrão é um pouco de dica / informação. Está sempre localizado em/sbin/init
sistemas sysvinit.sysvinit
Também isto:
Conclusões
Portanto, não parece haver uma maneira de fazer isso, mas você pode formular um conjunto de verificações que identifiquem qual sistema init você está usando com um grau de confiança bastante alto.
fonte
pgrep systemd >/dev/null && echo init system: systemd
/usr/lib/systemd/systemd
se systemd é usado, é uma suposição falsa. No meu sistema, por exemplo, o PID # 1 é/sbin/init
(eu uso o systemd). Depende da distribuição.pgrep systemd >/dev/null && echo init system: systemd -> init system: systemd
etype init -> init is /sbin/init
Não é tão eficiente, mas eu parece funcionar.
Ele imprimirá mais linhas se mais de uma sequência corresponder, o que pode ser traduzido para "Não é possível adivinhar". As strings usadas no grep podem ser levemente modificadas, mas quando testadas no seguinte, eu sempre tenho uma linha.
Uma abordagem mais simplista da mesma solução (mas para na primeira partida)
fonte
Às vezes é tão fácil quanto usar
ls
:Acho que se
/sbin/init
não for um link simbólico, você precisará verificar outras sugestões a seguir em outras respostas.fonte
É para isso que servem os pacotes específicos da distribuição. Há muito mais para instalar o software corretamente do que apenas detectar o sistema init. Muitas distribuições usam o SysVinit, mas nem todas escrevem seus scripts de inicialização da mesma maneira. A maneira correta de resolver isso é incluir todas as diferentes variantes e agrupá-las usando arquivos de especificação com nomes de dependência específicos de distribuição para distribuições rpm, arquivos deb para sistemas baseados em apt, etc. Quase todas as distribuições possuem algum tipo de especificação de pacote. pode escrever incluindo dependências, scripts, scripts init etc. Não reinvente a roda aqui.
Não. O que nos leva de volta a 1. Se você precisar do bash, deve ser uma dependência. Você pode especificar essa verificação como parte dos scripts de configuração, mas também deve estar nas descrições dos pacotes.
Editar: use sinalizadores no script de configuração, como
--with upstart
ou--without sysvinit
. Escolha um padrão sensato e, em seguida, os scripts que empacotam seu software para outras distribuições podem optar por executá-lo com outras opções.fonte
No Gentoo, dê uma olhada no pid 1:
Se for
init
, então o sistema init éOpenRC
. Se forsystemd
, então o sistema init ésystemd
.Você pode detectar o Gentoo com
[ -f /etc/gentoo-release ]
.Outro método no Gentoo é usar
profile-config show
, o que mostrará qual perfil padrão está sendo usado. Todos os perfis, exceto os dois que terminam em / systemd, usam o init do OpenRC. Lembre-se de que eles são apenas representativos de um padrão e é possível que o usuário tenha tomado medidas para substituir esse padrão e pode não ser indicativo do gerenciador de init realmente em uso.fonte
p
opção (idêntico ao-p
e--pid
) para selecionar por PID. O snippet acima é realmente a saída paraps u --pid 1
.No debian / sbin / init há um link simbólico para o seu init padrão,
fornecerá as informações que você está procurando.
fonte
init
posso instalar no Ubuntu 14.04?Simplesmente entrar no processo com o PID 1 dirá:
fonte
proc
sistema de arquivos ...A inspeção dos descritores de arquivos também pode ajudar. E é realmente executando init (o Debian stretch atualmente permite ter mais sistemas init instalados) :-)
Provavelmente, a maneira mais segura de verificar o busybox seria
check /proc/1/exe
, pois o busybox geralmente usa links simbólicos:Portanto, a verificação pode ser:
fonte
/run/systemd/system
.Não conheço outros sistemas que não sejam o Debian (wheezy) / ou Ubuntu (14.10.), Mas testei esses problemas com o
file
comando antigo .Dê isso:
Os sistemas Debian com
systemd
(por exemplo, sid) mostram isso:fonte
file /sbin/init /sbin/init: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, BuildID[sha1]=0x8c68a736c6a4e6fadf22d5ac9debf11e79c6bdcd, stripped
significa que usamos o SYSV aqui. A saída para o ubuntu é mostrada na minha resposta.file /sbin/init
retornei "executável" em todos os sistemas. Ele também retorna o mesmo em um CentOS 5.8, um SLES 10, um Ubuntu 8.04, basicamente em todos os sistemas em que posso colocar minhas mãos. Então, até onde eu sei, nem funciona para iniciantes e Ubuntu.Eu também tive esse mesmo problema e fiz muitos testes em algumas máquinas RedHat / CentOS / Debian / Ubuntu / Mint. Acabei com isso, com bons resultados.
Encontre o nome do executável com o PID 1:
Se for systemd ou Upstart, problema resolvido. Se for "init", pode ser um link simbólico ou algo diferente de um nome inicial. Continue.
Encontre o caminho real para o executável (funcione apenas como root):
Se
init
for um link simbólico para o Upstart ou systemd, o problema foi resolvido. Caso contrário, é quase certo que você tem o SysV init. Mas pode ser um executável com o nome errado. Continue.Encontre o pacote que fornece o executável. Infelizmente, isso depende da distribuição:
Então, se você deseja criar um script que (a parte mais engraçada, IMHO), esses são meus argumentos (executados como root):
fonte
init --version
para obter as informações.Isso é realmente fácil para alguns sistemas init. Para systemd:
para iniciante:
para qualquer outra coisa, você pode simplesmente assumir com base na distribuição (iniciada no OS X, sysvinit no Debian, OpenRC no Gentoo).
fonte
Aqui está um script bash para fazer a detecção. Ele verifica apenas o início e o systemd no momento, mas deve ser fácil de estender. Peguei isso no código que contribuí para o script de instalação do driver DisplayLink .
fonte
/proc
amarras está relacionado ao Linux (se configurado adequadamente) e a um ou dois outros - certamente está longe de ser universal.Existem muitas armadilhas de compatibilidade ao testar systemd vs initd. Isso realmente funciona no OpenSuSE 42.1:
ps --pid 1 | grep -q systemd && echo 'systemd' || echo 'init'
fonte
Para
systemd
:fonte
Minha solução: verifique o comando em execução como processo com o ID 1.
No momento, tenho acesso apenas às máquinas Init e SystemD, portanto não sei como o Upstart ou o macOS (OS X) serão detectados, mas continuarei pesquisando.
fonte
fonte