Detecta el sistema init usando el shell

90

Esto puede tener más que ver con la detección de sistemas operativos, pero específicamente necesito el sistema init actualmente en uso en el sistema.

Fedora 15 y Ubuntu ahora usan systemd, Ubuntu solía usar Upstart (tiempo predeterminado por defecto hasta 15.04), mientras que otros usan variaciones del Sistema V.

Tengo una aplicación que estoy escribiendo para ser un demonio multiplataforma. Los scripts de inicio se generan dinámicamente en función de los parámetros que se pueden pasar en la configuración.

Lo que me gustaría hacer es solo generar el script para el sistema de inicio particular que están utilizando. De esta manera, el script de instalación se puede ejecutar razonablemente sin parámetros como root y el demonio se puede "instalar" automáticamente.

Esto es lo que se me ocurrió:

  • Busque systemd, upstart, etc. en / bin
  • Compare / proc / 1 / comm con el systemd, upstart, etc.
  • Pregunta al usuario

¿Cuál sería la mejor forma cruzada / plataforma de hacer esto?

Tipo de relacionado, ¿puedo depender de bash para estar en la mayoría de * nix o depende de la distribución / SO?

Plataformas objetivo:

  • Mac OS
  • Linux (todas las distribuciones)
  • BSD (todas las versiones)
  • Solaris, Minix y otros * nix
beatgammit
fuente
1
Solo para agregar mis dos centavos, bash no está instalado por defecto en FreeBSD.
Chinmay Kanchi
@tjameson, ¿encontraste una forma más directa? Estoy buscando lo mismo, pero las respuestas aquí son solo instrucciones, no respuestas directas. En particular 1) ubicaciones de script para buscar y 2) detectar el sistema init en efecto, en caso de que haya varios instalados (bash fue respondido directamente).
n611x007
3
@naxa - Respuesta corta, no. Respuesta larga, puedes llegar bastante lejos con ps -p 1 -o command(imprime la ruta a la actual init). En Arch Linux y Fedora (IIRC), es un enlace simbólico al systemdbinario (probablemente igual en todos los systemdsistemas). El upstart, init --helpimprimirá información de uso, y en mi casilla, upstartse menciona dónde dice a quién enviar un correo electrónico. En FreeBSD (sysV), esto devolverá un error. Puede haber pistas similares en otros sistemas, pero desde que hice esta pregunta, decidí crearlas para todas las plataformas y hacer paquetes separados para cada una.
beatgammit
gracias gran información! Saltando de eso, he aprendido que sudo lsof -a -p 1 -d txtpuede dar resultados aún más exactos. pspuede imprimir un nombre arbitrario, mientras que con lsofusted obtendrá la ruta real ejecutable. (Ver mi pregunta unix.stackexchange.com/questions/102453/… )
n611x007
1
Ninguna de las respuestas o comentarios en la pregunta vinculada está relacionada con bash. Las soluciones también deberían ser aplicables a su caso.
Marco

Respuestas:

30

Para la segunda pregunta, la respuesta es no y debería echar un vistazo a Recursos para la programación de shell portátil .

En cuanto a la primera parte, antes que nada, ciertamente debes tener cuidado. Yo diría que realice varias pruebas para asegurarse , porque el hecho de que alguien tenga instalado systemd (por ejemplo) no significa que realmente se use como predeterminado init. Además, mirar /proc/1/commpuede ser engañoso, porque algunas instalaciones de varios programas init pueden hacer automáticamente /sbin/initun enlace simbólico o incluso una versión renombrada de su programa principal.

Tal vez lo más útil podría ser mirar el tipo de scripts de inicio, porque eso es lo que realmente creará, sin importar qué los ejecute.

Como nota al margen, también puede echar un vistazo a OpenRC, que tiene como objetivo proporcionar una estructura de scripts de inicio que sea compatible con los sistemas Linux y BSD.

rozcietrzewiacz
fuente
2
¿Qué quieres decir con "mira el tipo de guiones de inicio"? A menudo, diferentes sistemas de inicio colocan sus scripts / archivos en algún lugar además /etc/init, como systemd los coloca /etc/systemd. Si tuviera que hacer que mi script asimilara estos, podría tomar un poco de tiempo. Ah, y gracias por el enlace BTW para la programación de shell portátil.
beatgammit
1
Quise decir que algunas implementaciones de init se pueden ajustar para hacer uso de diferentes tipos y ubicaciones de scripts de inicio (como /etc/rc.d/o /etc/init.d/). Y debe ajustar adecuadamente su programa en el momento de la instalación para utilizar la estructura que se utiliza en el sistema dado.
rozcietrzewiacz
2
Entonces, ¿estás diciendo que no hay una forma confiable de detectar el sistema init mediante programación? Hacer que el usuario pase los parámetros es ciertamente más seguro, pero si el usuario no pasa nada, ¿cuál sería la mejor manera de adivinar?
beatgammit
No tengo idea de cuál será la mejor manera para su programa ; todo depende de qué sistemas terminará ejecutándose el programa. No he usado demasiadas distribuciones, pero estaba tratando de compartir mis observaciones para ayudarlo. Es una parte difícil de la secuencia de comandos que está a punto de probar y traté de darle alguna visión sobre el terreno: debe llegar a la respuesta final usted mismo o esperar más pistas.
rozcietrzewiacz
Genial, gracias por toda tu ayuda. Definitivamente me has señalado en la dirección correcta.
beatgammit
58

Me metí en este problema y decidí hacer algunas pruebas. Estoy totalmente de acuerdo con la respuesta de que uno debe empaquetar para cada distribución por separado, pero a veces hay problemas prácticos que lo impiden (no menos mano de obra).

Entonces, para aquellos que quieren "autodetectarse", esto es lo que he descubierto en un conjunto limitado de distribuciones (más abajo):

  • Puedes decir advenedizo desde:

    [[ `/sbin/init --version` =~ upstart ]] && echo yes || echo no
  • Puedes distinguir systemd de:

    [[ `systemctl` =~ -\.mount ]] && echo yes || echo no
  • Puede distinguir sys-v init de:

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

Aquí están mis experimentos con la siguiente línea 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

en instancias ec2 (incluyo el ID de AMI de us-east):

  • ArchLinux: usando systemd (desde 2012.10.06 )
  • CentOS6.4 ami-52009e3b: uso de arranque
  • 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: uso de arranque
  • SLES 11 ami-e8084981: usando sysv-init
  • Ubuntu 10.04 ami-6b350a02: uso de arranque
  • Ubuntu 12.04 ami-b08b6cd8: uso de upstart
  • Ubuntu 14.04 ami-a427efcc: uso de arranque
  • Ubuntu 14.10 y versiones anteriores: usando systemd
  • AWS linux 2014.3.2 ami-7c807d14: uso de upstart
  • Fedora 19 ami-f525389c: usando systemd
  • Fedora 20 ami-21362b48: usando systemd

Para ser claros: ¡no estoy afirmando que esto sea infalible! , casi seguro que no lo es. También tenga en cuenta que, por comodidad, uso bash regexp match, que no está disponible en todas partes. Lo anterior es lo suficientemente bueno para mí en este momento. Sin embargo, si encuentra una distribución donde falla, avíseme e intentaré solucionarla si hay un IAM EC2 que reproduce el problema ...

TV
fuente
55
De acuerdo con la documentación de systemd ( sd_booted (3) ), la forma correcta de verificar systemd es verificar si el directorio /run/systemd/systemexiste.
Robie Basak
1
Agregaré a esta detección launchd, el sistema init en macOS: [[ $(ps 1) =~ 'launchd' ]] && echo yes || echo noprobado en MacBookPro, macOS Sierra Versión 10.12
Tony
También agregaría 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 procesos

Mirando la salida de un par de pscomandos que pueden detectar las diversas versiones de systemd& upstart, que podrían ser creadas de esta manera:

advenedizo

$ 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 atención al nombre del proceso que es PID # 1 también puede arrojar luz sobre qué sistema de inicio se está utilizando. En Fedora 19 (que usa systemd, por ejemplo:

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

Note que no lo es init. En Ubuntu con Upstart todavía está /sbin/init.

$ ps -efa|grep init
root         1     0  0 Jan02 ?        00:00:03 /sbin/init

NOTA: Pero use esto con un poco de precaución. No hay nada escrito en piedra que dice que un sistema de inicio particular que está siendo utilizado en una distribución dada ha de tener systemdcomo el 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

Mire los procesos con ppid 1 (hijos del proceso init). (Algunos de los) nombres de procesos secundarios pueden apuntar al sistema init en uso.

El sistema de archivos

Si interroga al initejecutable, también puede obtener información de él. Simplemente analizando la --versionsalida. Por ejemplo:

advenedizo

$ 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: El hecho de que initno se encuentre en su ubicación estándar es un poco indirecto. Siempre se encuentra en los /sbin/initsistemas sysvinit.

sysvinit

$ type init
init is /sbin/init

También esto:

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

Conclusiones

Por lo tanto, no parece haber una sola forma de hacerlo, pero podría formular un conjunto de comprobaciones que determinarían qué sistema de inicio está utilizando con un grado bastante alto de confianza.

slm
fuente
¿Qué tal:pgrep systemd >/dev/null && echo init system: systemd
Marco
Gracias, esto es exactamente lo que estaba buscando: algunos pasos a seguir para tratar de determinar el sistema init.
user369450
1
El PID # 1 no necesariamente es /usr/lib/systemd/systemdsi se usa systemd, es una suposición falsa. En mi sistema, por ejemplo, PID # 1 es /sbin/init(yo uso systemd). Es dependiente de la distribución.
Marco
En mi instalación de kubuntu 15.04, parece que tengo systemd y sysvinit. No sé por qué o qué significa eso, solo digo ... pgrep systemd >/dev/null && echo init system: systemd -> init system: systemdytype init -> init is /sbin/init
dotnetCarpenter
12

No es tan eficiente, pero parece que funciona.

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

Imprimirá más líneas si coinciden más de una cadena, lo que podría traducirse a "No puedo adivinar". Las cadenas utilizadas en grep podrían modificarse ligeramente, pero cuando se prueban en el siguiente sistema operativo siempre obtengo una línea.

  • RHEL 6.4 [UPSTART]
  • RHEL ES 4 (Actualización 7 de Nahant) [SYSVINIT]
  • Ubuntu 16.04.1 LTS [SYSTEMD]
  • Ubuntu 14.04.2 LTS [UPSTART]
  • Fedora versión 23 (shell en línea) [SYSTEMD]
  • Debian GNU / Linux 7 (shell en línea) [SYSTEMD]

Un enfoque más simplista de la misma solución (pero se detiene en el primer partido)

strings /sbin/init |
  awk 'match($0, /(upstart|systemd|sysvinit)/) { print toupper(substr($0, RSTART, RLENGTH));exit; }'
Marinos An
fuente
Buena primera respuesta. bienvenido a unix.se!
Olivier Dulac
Acabo de probar esto en una imagen acoplada predeterminada de Gentoo con OpenRC instalado, y devolvió SYSVINIT. De acuerdo con wiki.gentoo.org/wiki/Comparison_of_init_systems, el valor predeterminado para Gentoo es OpenRC, pero parece que OpenRC usa sysvinit. Cuando intento los comandos de OpenRC me sale "Estás intentando ejecutar un servicio OpenRC en un sistema que openrc no arrancó". ¿Hay alguna manera de distinguir entre sysvinit apropiado y OpenRC usando sysvinit?
Tudor
9

A veces es tan fácil como usar ls :

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

Supongo que si /sbin/initno es un enlace simbólico, tendrá que consultar las siguientes sugerencias en otras respuestas.

Skippy le Grand Gourou
fuente
3
  1. Para eso están los paquetes específicos de la distribución. Instalar el software correctamente es mucho más que simplemente detectar el sistema init. Muchas distribuciones usan SysVinit, pero no todas escriben sus scripts de inicio de la misma manera. La forma correcta de resolver esto es incluir todas las diferentes variantes y luego agruparlo usando archivos de especificaciones con nombres de dependencia específicos de la distribución para distribuciones rpm, archivos deb para sistemas basados ​​en apt, etc. Casi todas las distribuciones tienen algún tipo de especificación de paquete que usted puede escribir que incluye dependencias, guiones, guiones de inicio, etc. No vuelva a inventar la rueda aquí.

  2. No. Lo que nos lleva de nuevo a 1. Si necesita bash, debería ser una dependencia. Puede especificar esta verificación como parte de sus scripts de configuración, pero también debe estar en las descripciones del paquete.

Editar: use marcas en su script de configuración como --with upstarto --without sysvinit. Elija un valor predeterminado sensato, luego los scripts que empaquetan su software para otras distribuciones pueden elegir ejecutar esto con otras opciones.

Caleb
fuente
Hmph, así que parece que no puedo tener una solución de 'un script para gobernarlos a todos'. He visto muchos programas que usan autoconf o similar para manejar cosas multiplataforma, pero no parece que sea la herramienta adecuada para mi aplicación. ¿Es el mantenimiento de versiones para cada plataforma realmente la única solución confiable?
beatgammit
Un script de instalación para gobernarlos a todos es BadIdea. Termina fallando más lugares de los que funciona. Autoconf es bueno en lo que va. Trabaja duro para mantener tu software lo más genérico posible e incluye scripts de inicio alternativos en tu paquete. Configure las especificaciones del paquete para varias distribuciones principales. Si su software es bueno, puede hacer que otras personas lo ayuden a empaquetarlo para otros sistemas.
Caleb
@tjameson: Me acabo de dar cuenta de que olvidé lo más importante. Este tipo de cosas generalmente se realiza con interruptores pasados ​​al script de configuración. Las rutinas de compilación / paquete de cada distribución pueden llamar a diferentes conmutadores, y su configuración / creación solo tiene que saber qué conmutador se pasó, no detectar todas las configuraciones de software posibles.
Caleb
@ Caleb: Sí, ya tengo esa lógica allí, pero buena captura. Esperaba una manera de olfatear el sistema init para usar una suposición inteligente que un defecto sensato.
beatgammit
2

En Gentoo, eche un vistazo a 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]

Si es así init, entonces el sistema init es OpenRC. Si es así systemd, entonces el sistema init es systemd.

Puedes detectar Gentoo con [ -f /etc/gentoo-release ].

Otro método en Gentoo es el uso profile-config show, que mostrará qué perfil predeterminado está en uso. Todos los perfiles, excepto los dos que terminan en / systemd, usan el OpenRC init. Tenga en cuenta que estos son solo representativos de un valor predeterminado y es posible que el usuario haya tomado medidas para anular ese valor predeterminado y que no sea indicativo del gestor de inicio realmente en uso.

casey
fuente
Pregunta tonta, pero ¿cómo verifico el pid 1?
Faheem Mitha
Use la popción (idéntica a -py --pid) para seleccionar por PID. El fragmento anterior es en realidad la salida para ps u --pid 1.
José M. Benítez
2

En debian / sbin / init hay un enlace simbólico a su init predeterminado

ls -l /sbin/init

te dará la información que estás buscando.

$ ls -l /sbin/init 
lrwxrwxrwx 1 root root 20 nov 18 13:15 /sbin/init -> /lib/systemd/systemd
rmorelli74
fuente
1
No tan. En Ubuntu 14.04 con Upstart, no es un enlace simbólico.
muru
Instale otro sistema init y verifique nuevamente.
rmorelli74
¿Y qué otro initpuedo instalar en Ubuntu 14.04?
muru
... ¿por qué no sysv o systemd?
rmorelli74
1
No quiero hacer un voto negativo, solo quiero que especifique a qué versión de Debian es aplicable. (Y quizás reformule "basado en Debian" a "Debian" solamente, para que sea correcto.)
muru
2

Simplemente pasar por el proceso con PID 1 le dirá:

strings /proc/1/exe |grep -q sysvinit
strings /proc/1/exe |grep -q systemd
Cyrille Pontvieux
fuente
No todos los OSeS mencionados tienen un procsistema de archivos ...
Toby Speight
2

También puede ayudar la inspección de descriptores de archivos. Y es en realidad ejecutando init (Debian stretch actualmente permite tener más 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

Probablemente, la forma más segura de verificar si busybox es check /proc/1/exe, ya que busybox generalmente usa enlaces simbólicos:

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

Entonces el cheque podría 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"
pevik
fuente
También los sistemas con systemd suelen tener directorio /run/systemd/system.
pevik
2

No sé acerca de otros sistemas, entonces Debian (wheezy) / o Ubuntu (14.10.), Pero pruebo tales problemas con el filecomando antiguo .

file /sbin/init

da esto:

/sbin/init: symbolic link to 'upstart'

Los sistemas Debian con systemd(por ejemplo, sid) muestran esto:

# file /sbin/init 
/sbin/init: symbolic link to /lib/systemd/systemd
zzeroo
fuente
¿En qué sistema lo probaste? No hay tal cosa como Debian / Ubuntu y esto no funciona en Debian. ¿Lo probaste en Ubuntu?
terdon
Perdón por esta confusión, me refiero a Debian (wheezy) / o Ubuntu (14.10.). Salida en 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 SYSV aquí. La salida para ubuntu se muestra en mi respuesta.
zzeroo
Exactamente, por lo que parece que su solución solo funciona si se está utilizando Ubuntu y Ubuntu.
terdon
@terdon: En los sistemas (RHEL, Fedora) que ejecutan systemd, devuelve "enlace simbólico a ... systemd"; en los sistemas (Ubuntu) que se ejecutan en el arranque, devuelve "enlace simbólico al arranque"; en sistemas (RHEL, Ubuntu, Debian) que ejecutan SysV init, devuelve "ejecutable". Si bien eso no es una encuesta exhaustiva, y este método claramente no es 100% infalible, ¡está claramente mucho más cerca de "funciona para al menos las principales distribuciones" en lugar de "solo para principiantes y Ubuntu"!
psmears
1
@psmears si también funciona para algunos sistemas systemd, eso es realmente mejor (pero no se menciona en esta respuesta). Acabo de probar en un Debian que ejecuta sysvinit, y tres Ubuntus (10.04, 12.04 y 14.04, todos ejecutando desde el inicio) y devolví file /sbin/init"ejecutable" en todos los sistemas. También devuelve lo mismo en un CentOS 5.8, un SLES 10, un Ubuntu 8.04, básicamente en todos los sistemas que puedo tener en mis manos. Entonces, por lo que puedo decir, ni siquiera funciona para advenedizos y Ubuntu.
terdon
2

También tuve el mismo problema e hice muchas pruebas en algunas máquinas RedHat / CentOS / Debian / Ubuntu / Mint. Esto es con lo que terminé, con buenos resultados.

  1. Encuentre el nombre del ejecutable con PID 1:

    ps -p 1

    Si es systemd o Upstart, el problema está resuelto. Si es "init", puede ser un enlace simbólico o algo más que un nombre inicial. Adelante.

  2. Encuentre la ruta real para el ejecutable (solo funciona como root):

    ls -l `which init`

    Si inites un enlace simbólico a Upstart o systemd, el problema está resuelto. De lo contrario, es casi seguro que tiene SysV init. Pero puede ser un ejecutable mal nombrado. Adelante.

  3. Encuentra el paquete que proporciona el ejecutable. Desafortunadamente, esto depende de la distribución:

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

Luego, si desea escribir un script que (la parte más divertida, en mi humilde opinión), estos son mis frases (ejecutado 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  
Emerson Prado
fuente
1
No todos los sistemas operativos especificados tienen dpkg o rpm (este problema no es específico solo de su respuesta, por cierto).
Toby Speight
@ toby-speight Sí, claro. Tenga en cuenta que lo dije en mi respuesta, solo para aclarar la limitación.
Emerson Prado
En cuanto al paso 3, puede ejecutar init --versionpara obtener la información.
jarno
1

Esto es realmente fácil para algunos sistemas init. Para systemd:

test -d /run/systemd/system

para advenedizo:

initctl --version | grep -q upstart

para cualquier otra cosa, puede asumir en función de la distribución (lanzado en OS X, sysvinit en Debian, OpenRC en Gentoo).

CameronNemo
fuente
"asumir basado en la distribución" no funciona para Debian, donde se admiten al menos tres inits diferentes ...
Toby Speight
1

Aquí hay un script bash para hacer la detección. Por el momento, solo verifica el arranque y systemd, pero debería ser fácil de extender. Tomé esto del código que contribuí al script de instalación del controlador 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
}
Ben McCann
fuente
1
Creo que el uso de /procvínculos se relaciona con Linux (si está configurado adecuadamente) y uno o dos más; ciertamente, está lejos de ser universal.
Toby Speight
1

Hay muchas dificultades de compatibilidad al probar systemd vs initd. Esto realmente funciona en OpenSuSE 42.1:ps --pid 1 | grep -q systemd && echo 'systemd' || echo 'init'

David Lakatos
fuente
1

Para systemd:

if [[ `systemctl is-system-running` =~ running ]]; then echo using systemd; fi
guilhermebr
fuente
voto negativo porque esta respuesta no proporciona información nueva o diferente en comparación con las numerosas respuestas existentes.
jayhendren
@jayhendren No veo este fragmento en otro lugar. No está completo en sí mismo, y probablemente sería mejor como un comentario en contra de la respuesta unix.stackexchange.com/a/164092/100397 por TvE
roaima
Oh tienes razón @roaima. No es exactamente lo mismo que los demás. Busqué en la página una cadena no muy específica :)
jayhendren
1
Esta parece ser, de lejos, la respuesta más correcta :)
Jack O'Connor
1

Mi solución: verifique el comando que se ejecuta como proceso con 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

Por el momento, solo tengo acceso a las máquinas Init y SystemD, por lo que no puedo decir cómo se detectarán Upstart o macOS (OS X), pero seguiré buscando.

t0r0X
fuente
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
}
hxysayhi
fuente