Detectar o sistema init usando o shell


90

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

1
Apenas para adicionar meus dois centavos, o bash não está instalado por padrão no FreeBSD.
Chinmay Kanchi

@tjameson, você encontrou uma maneira mais direta? Estou procurando a mesma coisa, mas as respostas aqui são apenas instruções, não respostas diretas. Em particular 1) locais de script para pesquisar e 2) detectar o sistema init em vigor, caso existam vários instalados (o bash foi respondido diretamente).
N611x007

3
@naxa - Resposta curta, não. Resposta longa, você pode ir muito longe ps -p 1 -o command(imprime o caminho para o atual init). No Arch Linux e Fedora (IIRC), é um link simbólico para o systemdbinário (provavelmente o mesmo em todos os systemdsistemas). Ativado upstart, init --helpimprime 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.
Beatgammit #

obrigado ótima informação! Partindo disso, aprendi que sudo lsof -a -p 1 -d txtpode dar resultados ainda mais exatos. pspode imprimir um nome arbitrário, enquanto que lsofvocê obterá o caminho real do executável. (Veja minha pergunta unix.stackexchange.com/questions/102453/… )
n611x007

1
Nenhuma das respostas ou comentários na pergunta vinculada está relacionada ao bash. As soluções também devem ser aplicáveis ​​ao seu caso.
1013 Marco

Respostas:


30

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/commpode ser enganosa, porque algumas instalações de vários programas init podem criar automaticamente /sbin/initum 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.


2
O que você quer dizer com "veja o tipo de script init"? Frequentemente, diferentes sistemas init colocam seus scripts / arquivos em algum outro lugar /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.
Beatgammit

1
Eu quis dizer que algumas implementações de init podem ser ajustadas para usar tipos e locais de scripts de init diferentes (como /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.
rozcietrzewiacz

2
Então, você está dizendo que não há uma maneira confiável de detectar o sistema init programaticamente? Ter o usuário passando parâmetros é certamente mais seguro, mas se o usuário não passar nada, qual seria a melhor maneira de adivinhar?
Beatgammit 7/08

Não tenho idéia de qual será o melhor caminho para o seu programa - tudo depende de quais sistemas o programa acabará sendo executado. Não usei muitas distribuições, mas estava tentando compartilhar minhas observações para ajudá-lo. É uma parte difícil de script que você está prestes a tentar e tentei dar uma visão do campo - você deve chegar à resposta final ou aguardar mais dicas.
rozcietrzewiacz

Legal, obrigado por toda a sua ajuda. Você definitivamente me apontou na direção certa.
Beatgammit 7/08

58

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:

    [[ `/sbin/init --version` =~ upstart ]] && echo yes || echo no
  • Você pode dizer ao systemd em:

    [[ `systemctl` =~ -\.mount ]] && echo yes || echo no
  • Você pode dizer ao sys-v init em:

    [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]] && echo yes

Aqui estão minhas experiências com a seguinte linha de comando:

if [[ `/sbin/init --version` =~ upstart ]]; then echo using upstart;
elif [[ `systemctl` =~ -\.mount ]]; then echo using systemd;
elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then echo using sysv-init;
else echo cannot tell; fi

em instâncias ec2 (estou incluindo o ID da AMI nos EUA):

  • ArchLinux: using systemd (desde 2012.10.06 )
  • CentOS6.4 ami-52009e3b: usando upstart
  • CentOS7 ami-96a818fe: usando systemd
  • Debian 6 ami-80e915e9: usando sysv-init
  • Debian 7.5 ami-2c886c44: usando sysv-init
  • Debian 7.6 GCE container-vm: usando sysv-init
  • RHEL 6.5 ami-8d756fe4: usando upstart
  • SLES 11 ami-e8084981: usando sysv-init
  • Ubuntu 10.04 ami-6b350a02: usando upstart
  • Ubuntu 12.04 ami-b08b6cd8: usando upstart
  • Ubuntu 14.04 ami-a427efcc: usando upstart
  • Ubuntu 14.10 e mais recente: usando systemd
  • AWS linux 2014.3.2 ami-7c807d14: usando upstart
  • Fedora 19 ami-f525389c: usando systemd
  • Fedora 20 ami-21362b48: usando systemd

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 ...


5
De acordo com a documentação do systemd ( sd_booted (3) ), a maneira correta de verificar o systemd é verificar se o diretório /run/systemd/systemexiste.
precisa

1
Vou acrescentar a essa detecção launchd, o sistema init no macOS: [[ $(ps 1) =~ 'launchd' ]] && echo yes || echo notestado em um MacBookPro, macOS Sierra Versão 10.12
Tony

Eu também adicionaria o busybox:if [ -h /sbin/init -a $(readlink /sbin/init | grep busybox | wc -l) -gt 0 ]; then echo yes; else echo no; fi
Astrinus

18

Usando processos

Observando a saída de alguns pscomandos que podem detectar as várias versões do systemd& upstart, que podem ser criadas da seguinte maneira:

subir na vida

$ ps -eaf|grep '[u]pstart'
root       492     1  0 Jan02 ?        00:00:00 upstart-udev-bridge --daemon
root      1027     1  0 Jan02 ?        00:00:00 upstart-socket-bridge --daemon

systemd

$ ps -eaf|grep '[s]ystemd'
root         1     0  0 07:27 ?        00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 20
root       343     1  0 07:28 ?        00:00:03 /usr/lib/systemd/systemd-journald
root       367     1  0 07:28 ?        00:00:00 /usr/lib/systemd/systemd-udevd
root       607     1  0 07:28 ?        00:00:00 /usr/lib/systemd/systemd-logind
dbus       615     1  0 07:28 ?        00:00:13 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation

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:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 07:27 ?        00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 20

Observe que não é init. No Ubuntu com Upstart ainda está /sbin/init.

$ ps -efa|grep init
root         1     0  0 Jan02 ?        00:00:03 /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 systemdcomo o PID # 1.

genérico

$ (ps -eo "ppid,args" 2>/dev/null || echo "ps call error") \
    | awk 'NR==1 || $1==1' | less
 PPID   COMMAND
    1   /lib/systemd/systemd-journald
    1   /lib/systemd/systemd-udevd
    1   /lib/systemd/systemd-timesyncd

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 initexecutável, também poderá obter algumas informações. Simplesmente analisando a --versionsaída. Por exemplo:

subir na vida

$ sudo /sbin/init --version
init (upstart 1.5)
Copyright (C) 2012 Scott James Remnant, Canonical Ltd.

This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.

systemd

$ type init
init is /usr/sbin/init

NOTA: O fato de initnão estar em sua localização padrão é um pouco de dica / informação. Está sempre localizado em /sbin/initsistemas sysvinit.

sysvinit

$ type init
init is /sbin/init

Também isto:

$ sudo init --version
init: invalid option -- -
Usage: init 0123456SsQqAaBbCcUu

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.


Que tal:pgrep systemd >/dev/null && echo init system: systemd
Marco

Obrigado, é exatamente isso que eu estava procurando: algumas etapas a serem seguidas para tentar determinar o sistema init.
User369450

1
O PID # 1 não é necessariamente /usr/lib/systemd/systemdse systemd é usado, é uma suposição falsa. No meu sistema, por exemplo, o PID # 1 é /sbin/init(eu uso o systemd). Depende da distribuição.
10243 Marco Marco

Na minha instalação do kubuntu 15.04, eu pareço ter systemd e sysvinit. Não sei por que ou o que isso significa, apenas dizendo .. pgrep systemd >/dev/null && echo init system: systemd -> init system: systemdetype init -> init is /sbin/init
dotnetCarpenter

12

Não é tão eficiente, mas eu parece funcionar.

strings /sbin/init | grep -q "/lib/systemd" && echo SYSTEMD
strings /sbin/init | grep -q "sysvinit" && echo SYSVINIT
strings /sbin/init | grep -q "upstart" && echo UPSTART

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.

  • RHEL 6.4 [UPSTART]
  • RHEL ES 4 (Atualização Nahant 7) [SYSVINIT]
  • Ubuntu 16.04.1 LTS [SYSTEMD]
  • Ubuntu 14.04.2 LTS [UPSTART]
  • Versão 23 do Fedora (shell online) [SYSTEMD]
  • Debian GNU / Linux 7 (shell online) [SYSTEMD]

Uma abordagem mais simplista da mesma solução (mas para na primeira partida)

strings /sbin/init |
  awk 'match($0, /(upstart|systemd|sysvinit)/) { print toupper(substr($0, RSTART, RLENGTH));exit; }'

boa primeira resposta. bem-vindo ao unix.se!
precisa

Eu apenas tentei isso em uma imagem de janela de encaixe padrão do Gentoo com o OpenRC instalado e ele retornou o SYSVINIT. De acordo com wiki.gentoo.org/wiki/Comparison_of_init_systems, o padrão para o Gentoo é o OpenRC, mas parece que o OpenRC usa o sysvinit. Quando tento os comandos do OpenRC, recebo "Você está tentando executar um serviço OpenRC em um sistema que o openrc não inicializou". Existe uma maneira de distinguir entre sysvinit apropriado e OpenRC usando sysvinit?
tudor

9

Às vezes é tão fácil quanto usar ls :

$ ls -l /sbin/init
lrwxrwxrwx 1 root root 20 juin  25 12:04 /sbin/init -> /lib/systemd/systemd

Acho que se /sbin/initnão for um link simbólico, você precisará verificar outras sugestões a seguir em outras respostas.


3
  1. É 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.

  2. 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 upstartou --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.


Hmph, parece que não posso ter uma solução 'um script para governar todos eles'. Eu já vi muitos programas que usam o autoconf ou semelhante para lidar com coisas de plataforma cruzada, mas não parece ser a ferramenta certa para o meu aplicativo. A manutenção de versões para cada plataforma é realmente a única solução confiável?
Beatgammit 7/08

Um script de instalação para governar todos eles é um BadIdea. Ele acaba falhando em mais lugares do que funciona. O Autoconf é bom na medida em que vai. Trabalhe duro para manter o final do software o mais genérico possível e inclua scripts init alternativos em seu pacote. Configure as especificações do pacote para várias distros principais. Se o seu software for bom, você pode pedir a outras pessoas para ajudá-lo a empacotá-lo para outros sistemas.
Caleb

@tjameson: Acabei de perceber que esqueci a parte mais importante. Esse tipo de coisa geralmente é feito com os switches passados ​​para o script de configuração. As rotinas de compilação / pacote de cada distribuição podem chamar comutadores diferentes, e o seu configure / make precisa apenas saber qual comutador foi aprovado, não detectar todas as configurações possíveis de software.
Caleb

@ Caleb- Sim, eu já tenho essa lógica lá, mas é bom. Eu estava esperando uma maneira de farejar o sistema init para usar um palpite inteligente do que um padrão sensato.
Beatgammit 7/08

2

No Gentoo, dê uma olhada no pid 1:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4216   340 ?        Ss    2013   0:57 init [3]

Se for init, então o sistema init é OpenRC. Se for systemd, 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.


Pergunta idiota, mas como verifico o pid 1?
Faheem Mitha

Use a popção (idêntico ao -pe --pid) para selecionar por PID. O snippet acima é realmente a saída para ps u --pid 1.
José M. Benítez

2

No debian / sbin / init há um link simbólico para o seu init padrão,

ls -l /sbin/init

fornecerá as informações que você está procurando.

$ ls -l /sbin/init 
lrwxrwxrwx 1 root root 20 nov 18 13:15 /sbin/init -> /lib/systemd/systemd

1
Não tão. No Ubuntu 14.04 com Upstart, não é um link simbólico.
Muru

Instale outro sistema init e verifique novamente.
precisa saber é o seguinte

E qual outro initposso instalar no Ubuntu 14.04?
Muru

... por que não sysv ou systemd?
precisa saber é o seguinte

1
Não quero reduzir o voto, apenas quero que você especifique a qual versão do Debian é aplicável. (E talvez reformular "baseada no Debian" para "Debian" somente, para que se torne correta.)
Muru

2

Simplesmente entrar no processo com o PID 1 dirá:

strings /proc/1/exe |grep -q sysvinit
strings /proc/1/exe |grep -q systemd

Nem todos os SOs mencionados têm um procsistema de arquivos ...
Toby Speight

2

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) :-)

$ ls -l /proc/1/fd |grep systemd
lrwx------ 1 root root 64 srp 14 13:56 25 -> /run/systemd/initctl/fifo
lr-x------ 1 root root 64 srp 14 13:56 6 -> /sys/fs/cgroup/systemd

$ ls -l /proc/1/fd |grep /run/initctl # sysvinit
lrwx------ 1 root root 64 srp 14 14:04 10 -> /run/initctl

$ ls -l /proc/1/fd |grep upstart
l-wx------ 1 root root 64 srp 13 16:09 13 -> /var/log/upstart/mysql.log.1 (delete
l-wx------ 1 root root 64 srp 13 16:09 9 -> /var/log/upstart/dbus.log.1 (deleted)

$ ls -l /proc/1/fd # busybox
total 0
lrwx------    1 root     root          64 Jan  1 00:00 0 -> /dev/console
lrwx------    1 root     root          64 Jan  1 00:00 1 -> /dev/console
lrwx------    1 root     root          64 Jan  1 00:00 2 -> /dev/console

Provavelmente, a maneira mais segura de verificar o busybox seria check /proc/1/exe, pois o busybox geralmente usa links simbólicos:

$ ls -l /proc/1/exe 
lrwxrwxrwx    1 root     root          0 Jan  1 00:00 /proc/1/exe -> /bin/busybox

Portanto, a verificação pode ser:

{ ls -l /proc/1/fd |grep -q systemd && echo "init: systemd"; } || \
{ ls -l /proc/1/fd |grep -q /run/initctl && echo "init: sysvinit"; } || \
{ ls -l /proc/1/fd |grep -q upstart && echo "init: upstart"; } || \
{ ls -l /proc/1/exe |grep -q busybox && echo "init: busybox"; } || \
echo "unknown init"

Também sistemas com systemd geralmente possuem diretório /run/systemd/system.
pevik 11/09/2015

2

Não conheço outros sistemas que não sejam o Debian (wheezy) / ou Ubuntu (14.10.), Mas testei esses problemas com o filecomando antigo .

file /sbin/init

Dê isso:

/sbin/init: symbolic link to 'upstart'

Os sistemas Debian com systemd(por exemplo, sid) mostram isso:

# file /sbin/init 
/sbin/init: symbolic link to /lib/systemd/systemd

Em que sistema você testou? Não existe o Debian / Ubuntu e isso não funciona no Debian. Você tentou no Ubuntu?
terdon

Desculpe por essa confusão, refiro-me ao Debian (wheezy) / ou Ubuntu (14.10.). Saída no debian: 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.
Zzeroo

Exatamente, sua solução parece funcionar apenas se estiver usando o upstart e o Ubuntu.
terdon

@terdon: Nos sistemas (RHEL, Fedora) executando systemd, retorna "link simbólico para ... systemd"; em sistemas (Ubuntu) executando upstart, ele retorna "link simbólico para upstart"; em sistemas (RHEL, Ubuntu, Debian) executando o SysV init, ele retorna "executável". Embora essa não seja uma pesquisa abrangente, e esse método claramente não seja 100% infalível, é claramente muito mais próximo de "funciona para pelo menos as principais distros" em vez de "apenas para iniciantes e Ubuntu"!
Psmears # 20/14

1
@psmears se também funcionar para alguns sistemas systemd, é realmente melhor (mas não mencionado nesta resposta). Acabei de testar em um Debian executando o sysvinit e três Ubuntus (10.04, 12.04 e 14.04, todos iniciando) e file /sbin/initretornei "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.
terdon

2

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.

  1. Encontre o nome do executável com o PID 1:

    ps -p 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.

  2. Encontre o caminho real para o executável (funcione apenas como root):

    ls -l `which init`

    Se initfor 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.

  3. Encontre o pacote que fornece o executável. Infelizmente, isso depende da distribuição:

    dpkg-query -S (executable real path) # Debian  
    rpm -qf (executable real path) # RedHat  

Então, se você deseja criar um script que (a parte mais engraçada, IMHO), esses são meus argumentos (executados como root):

ls -l $(which $(ps -p 1 o comm)) | awk '{ system("dpkg-query -S "$NF) }' # Debian  

ls -l $(which $(ps -p 1 o comm)) | awk '{ system("rpm -qf "$NF) }' # RedHat  

1
Nem todos os sistemas operacionais especificados possuem dpkg ou rpm (esse problema não é específico apenas à sua resposta, BTW).
Toby Speight

@ toby-speight Sim, claro. Observe que afirmei isso em minha resposta, apenas para deixar clara a limitação.
Emerson Prado

Quanto à etapa 3, você pode executar init --versionpara obter as informações.
Jarno

1

Isso é realmente fácil para alguns sistemas init. Para systemd:

test -d /run/systemd/system

para iniciante:

initctl --version | grep -q upstart

para qualquer outra coisa, você pode simplesmente assumir com base na distribuição (iniciada no OS X, sysvinit no Debian, OpenRC no Gentoo).


"assumir com base na distribuição" não funciona para o Debian, onde pelo menos três inits diferentes são suportadas ...
Toby Speight

1

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 .

detect_distro()
{
  # init process is pid 1
  INIT=`ls -l /proc/1/exe`
  if [[ $INIT == *"upstart"* ]]; then
    SYSTEMINITDAEMON=upstart
  elif [[ $INIT == *"systemd"* ]]; then
    SYSTEMINITDAEMON=systemd
  elif [[ $INIT == *"/sbin/init"* ]]; then
    INIT=`/sbin/init --version`
    if [[ $INIT == *"upstart"* ]]; then
      SYSTEMINITDAEMON=upstart
    elif [[ $INIT == *"systemd"* ]]; then
      SYSTEMINITDAEMON=systemd
    fi
  fi

  if [ -z "$SYSTEMINITDAEMON" ]; then
    echo "WARNING: Unknown distribution, assuming defaults - this may fail." >&2
  else
    echo "Init system discovered: $SYSTEMINITDAEMON"
  fi
}

1
Eu acho que o uso de /procamarras está relacionado ao Linux (se configurado adequadamente) e a um ou dois outros - certamente está longe de ser universal.
Toby Speight

1

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'


1

Para systemd:

if [[ `systemctl is-system-running` =~ running ]]; then echo using systemd; fi

voto negativo porque esta resposta não fornece nenhuma informação nova ou diferente em comparação com as inúmeras respostas existentes.
Jayhendren #

@jayhendren Não vejo esse trecho em outro lugar. Não é completo em si mesmo, e provavelmente melhor ficar como um comentário contra a resposta unix.stackexchange.com/a/164092/100397 pela TVE
roaima

Oh, você está certo @roaima. Não é exatamente o mesmo que os outros. Eu procurei a página para uma seqüência específica não demasiado :)
jayhendren

1
Este parece ser, de longe, a resposta mais correta :)
Jack O'Connor

1

Minha solução: verifique o comando em execução como processo com o ID 1.

case `cat /proc/1/comm` in
    init)    echo Init ;;
    systemd) echo SystemD ;;
    # add here other patterns
    *)       echo "unknown: '`cat /proc/1/comm`'" ;;
esac

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.


0
check(){
    if hash systemctl 2>/dev/null;
    then
        echo "there is systemd"
    fi

    if hash initctl 2>/dev/null;
    then
        echo "there is upStart"
    fi

    if [ -f "/etc/inittab"];
    then
        echo "there is systemV"
    fi
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.