Cela a peut-être plus à voir avec la détection des systèmes d'exploitation, mais j'ai particulièrement besoin du système init actuellement utilisé sur le système.
Fedora 15 et Ubuntu utilisent maintenant systemd, Ubuntu utilisait Upstart (valeur par défaut jusqu'à 15.04), tandis que d'autres utilisent des variantes de System V.
J'ai une application que je suis en train d'écrire pour être un démon multi-plateforme. Les scripts d'initialisation sont générés dynamiquement en fonction de paramètres pouvant être transmis lors de la configuration.
Ce que j'aimerais faire, c'est générer uniquement le script pour le système d'init particulier qu'ils utilisent. De cette façon, le script d'installation peut être exécuté raisonnablement sans paramètre en tant que root et le démon peut être "installé" automatiquement.
C'est ce que je suis venu avec:
- Recherchez systemd, upstart, etc. dans / bin
- Comparez / proc / 1 / comm avec le systemd, upstart, etc
- Demander à l'utilisateur
Quel serait le meilleur moyen de procéder de la sorte?
Type de parenté, puis-je compter sur bash pour être sur la majorité de * nix ou est-ce que cela dépend de la distribution / du système d'exploitation?
Plateformes cibles:
- Mac OS
- Linux (toutes les distributions)
- BSD (toutes les versions)
- Solaris, Minix et autres * nix
la source
ps -p 1 -o command
(affiche le chemin d'accès au courantinit
). Sur Arch Linux et Fedora (IIRC), il s’agit d’un lien symbolique vers lesystemd
binaire (probablement le même sur tous lessystemd
systèmes). Le surupstart
,init --help
imprimera les informations d'utilisation, et sur ma boîte,upstart
est mentionné où il est dit à qui envoyer un courriel. Sur FreeBSD (sysV), cela retournera une erreur. Il peut y avoir des indices similaires sur d’autres systèmes, mais depuis que je pose cette question, j’ai décidé de les créer pour toutes les plateformes et de créer des packages distincts pour chacune d’elles.sudo lsof -a -p 1 -d txt
peut donner des résultats encore plus exacts.ps
peut imprimer un nom arbitraire, alors quelsof
vous obtiendrez le vrai chemin d’exécutable. (Voir ma question unix.stackexchange.com/questions/102453/… )Réponses:
Pour la deuxième question, la réponse est non et vous devriez jeter un coup d'œil à Ressources pour la programmation shell portable .
Pour ce qui est de la première partie, il faut d’abord faire attention. Je dirais de faire plusieurs tests pour être sûr - parce que le fait que quelqu'un ait installé systemd (par exemple) ne signifie pas qu'il est réellement utilisé par défaut
init
. En outre, regarder/proc/1/comm
peut être trompeur, car certaines installations de différents programmes init peuvent automatiquement créer/sbin/init
un lien symbolique ou même une version renommée de leur programme principal.Le plus utile serait peut-être d’examiner le type de script init, car c’est ce que vous allez réellement créer, quel que soit son exécution.
En passant , vous pouvez également consulter OpenRC, qui vise à fournir une structure de scripts init compatible avec les systèmes Linux et BSD.
la source
/etc/init
, comme le fait systemd/etc/systemd
. Si je devais avoir mon script grok ces derniers, cela pourrait prendre un peu de temps. Oh, et merci pour le lien BTW pour la programmation de shell portable./etc/rc.d/
ou/etc/init.d/
). Et vous devez ajuster correctement votre programme au moment de l'installation pour utiliser la structure utilisée sur le système donné.J'ai moi-même abordé ce problème et décidé de faire des tests. Je suis tout à fait d’accord avec la réponse selon laquelle il faut emballer séparément chaque distribution, mais il existe parfois des problèmes pratiques qui l’empêchent (notamment le manque de main-d’œuvre).
Donc, pour ceux qui veulent "détecter automatiquement", voici ce que j'ai découvert sur un nombre limité de distributions (voir ci-dessous):
Vous pouvez identifier dès le départ:
Vous pouvez dire à systemd de:
Vous pouvez dire à sys-v init de:
Voici mes expériences avec la ligne de commande suivante:
sur les instances ec2 (j'inclus l'identifiant d'AMI us-east):
Juste pour être clair: je ne prétends pas que c'est infaillible! ce n'est certainement pas le cas. Notez également que par commodité, j'utilise des correspondances bash regexp, qui ne sont pas disponibles partout. Ce qui précède me suffit pour le moment. Cependant, si vous trouvez une distribution où elle échoue, faites-le moi savoir et j'essaierai de la réparer s'il existe une AMI EC2 qui reproduit le problème ...
la source
/run/systemd/system
existe.launchd
, le système init sur macOS:[[ $(ps 1) =~ 'launchd' ]] && echo yes || echo no
testé sur un MacBookPro, macOS Sierra Version 10.12if [ -h /sbin/init -a $(readlink /sbin/init | grep busybox | wc -l) -gt 0 ]; then echo yes; else echo no; fi
Utiliser des processus
En regardant le résultat de quelques
ps
commandes capables de détecter les différentes versions desystemd
&upstart
, qui pourraient être conçues comme suit:parvenu
systemd
Faire attention au nom du processus qui est le PID # 1 peut aussi potentiellement éclairer le système init utilisé. Sur Fedora 19 (qui utilise
systemd
, par exemple:Remarquez que non
init
. Sur Ubuntu avec Upstart c'est encore/sbin/init
.NOTE: Mais utilisez ceci avec un peu de prudence. Rien dans la pierre ne dit qu'un système d'initialisation particulier utilisé sur une distribution donnée doit avoir
systemd
le PID # 1.générique
Regardez les processus avec ppid 1 (enfants du processus init). Certains noms de processus enfants peuvent pointer vers le système init utilisé.
Le système de fichiers
Si vous interrogez l'
init
exécutable, vous pouvez également obtenir des informations à ce sujet. Simplement analyser la--version
sortie. Par exemple:parvenu
systemd
REMARQUE: le fait de
init
ne pas se trouver à son emplacement standard est un indice. Il est toujours situé/sbin/init
sur les systèmes sysvinit.sysvinit
Aussi ceci:
Conclusions
Il ne semble donc pas exister de solution unique, mais vous pouvez formuler une série de vérifications permettant de déterminer le système d’initialisation que vous utilisez avec un degré de confiance assez élevé.
la source
pgrep systemd >/dev/null && echo init system: systemd
/usr/lib/systemd/systemd
si systemd est utilisé, c'est une fausse hypothèse. Sur mon système, par exemple, le PID n ° 1 est/sbin/init
(j'utilise systemd). C'est dépendant de la distribution.pgrep systemd >/dev/null && echo init system: systemd -> init system: systemd
ettype init -> init is /sbin/init
Pas si efficace que ça mais ça a l'air de marcher.
Il imprimera plus de lignes si plus d'une chaîne correspond, ce qui pourrait être traduit par "Je ne peux pas deviner". Les chaînes utilisées dans grep peuvent être légèrement modifiées, mais lorsqu’elles ont été testées dans l’os suivant, j’ai toujours une ligne.
Une approche plus simpliste de la même solution (mais cela s'arrête au premier match)
la source
Parfois, c'est aussi simple que d'utiliser
ls
:J'imagine que s'il
/sbin/init
ne s'agit pas d'un lien symbolique, vous devrez vérifier les suggestions suivantes dans les autres réponses.la source
C’est ce à quoi servent les packages spécifiques à la distribution. Pour installer le logiciel correctement, il ne suffit pas de détecter le système init. Beaucoup de distributions utilisent SysVinit mais toutes n'écrivent pas leurs scripts init de la même manière. Pour résoudre ce problème, la meilleure solution consiste à inclure toutes les variantes et à les regrouper à l’aide de fichiers de spécification avec des noms de dépendances spécifiques à la distribution pour les distributions rpm, les fichiers deb pour les systèmes apt, etc. peut écrire avec des dépendances, des scripts, des scripts d'initialisation, etc. Ne réinventez pas la roue ici.
Ce qui nous ramène à 1. Si vous avez besoin de bash, cela devrait être une dépendance. Vous pouvez spécifier cette vérification dans vos scripts de configuration, mais elle devrait également figurer dans les descriptions de paquet.
Modifier: utilisez des indicateurs sur votre script de configuration, tels que
--with upstart
ou--without sysvinit
. Choisissez une valeur par défaut, les scripts qui conditionnent votre logiciel pour d’autres distributions peuvent choisir de l’exécuter avec d’autres options.la source
Sur Gentoo, regardez pid 1:
Si c'est le cas
init
, le système init estOpenRC
. Si c'est le cassystemd
, le système init estsystemd
.Vous pouvez détecter Gentoo avec
[ -f /etc/gentoo-release ]
.Une autre méthode sur Gentoo consiste à utiliser
profile-config show
, qui montrera quel profil par défaut est utilisé. Tous les profils, sauf les deux se terminant par / systemd, utilisent l'init OpenRC. N'oubliez pas que ces éléments ne sont représentatifs que d'un paramètre par défaut et qu'il est possible que l'utilisateur ait pris des mesures pour remplacer ce paramètre par défaut.la source
p
option (identique à-p
et--pid
) pour sélectionner par PID. L'extrait ci-dessus est en fait la sortie pourps u --pid 1
.Sur debian / sbin / init est un lien symbolique vers votre init par défaut afin
vous donnera l'information que vous cherchez.
la source
init
puis-je installer sur Ubuntu 14.04?En entrant simplement dans le processus avec le PID 1, vous apprendrez:
la source
proc
système de fichiers ...L'inspection des descripteurs de fichiers peut également aider. Et c'est à partir de l'initialisation en cours (l'étirement de Debian permet actuellement d'installer plus de systèmes d'initialisation) :-)
Le moyen le plus sûr de rechercher une busybox serait de le faire
check /proc/1/exe
, puisque busybox utilise généralement des liens symboliques:Donc, vérifier pourrait être:
la source
/run/systemd/system
.Je ne connais pas d’autres systèmes que Debian (Wheezy) / ou Ubuntu (14.10.), Mais j’ai testé de tels problèmes avec la
file
commande plain old .donne ça:
Les systèmes Debian avec
systemd
(par exemple, sid) montrent ceci:la source
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
signifie que nous utilisons SYSV ici. La sortie pour Ubuntu est montrée dans ma réponse.file /sbin/init
retourné "exécutable" sur tous les systèmes. Il retourne également la même chose sur CentOS 5.8, SLES 10, Ubuntu 8.04, en gros tous les systèmes sur lesquels je peux mettre la main. Donc, autant que je sache, cela ne fonctionne même pas pour Ubuntu et Upstart.J'ai également eu le même problème et fait beaucoup de tests sur certaines machines RedHat / CentOS / Debian / Ubuntu / Mint. C'est ce que j'ai fini avec, avec de bons résultats.
Trouvez le nom de l'exécutable avec le PID 1:
Si c'est systemd ou Upstart, le problème est résolu. Si c'est "init", il peut s'agir d'un lien symbolique ou de quelque chose d'autre qu'un nom initial. Aller de l'avant.
Trouvez le vrai chemin pour l'exécutable (ne travaillez que comme root):
Si
init
est un lien symbolique vers Upstart ou systemd, le problème est résolu. Sinon, il est presque certain que vous avez initié SysV. Mais cela peut être un exécutable mal nommé. Aller de l'avant.Trouvez le paquet qui fournit l'exécutable. Malheureusement, cela dépend de la distro:
Ensuite, si vous voulez écrire un script (la partie la plus drôle, à mon humble avis), voici mes one-liners (exécutés en tant que root):
la source
init --version
pour obtenir les informations.C'est vraiment facile pour certains systèmes init. Pour systemd:
pour le débutant:
pour toute autre chose, vous pouvez simplement supposer basé sur la distribution (lancé sur OS X, sysvinit sur Debian, OpenRC sur Gentoo).
la source
Voici un script bash pour effectuer la détection. Il ne vérifie que les versions récente et système du système, mais devrait être facile à étendre. J'ai pris cela dans le code que j'ai contribué au script d'installation du pilote DisplayLink .
la source
/proc
liens entre cela et Linux (si correctement configuré) et un ou deux autres - c’est certainement loin d’être universelle.Il y a de nombreux pièges de compatibilité lors du test de systemd vs initd. Cela fonctionne réellement sur OpenSuSE 42.1:
ps --pid 1 | grep -q systemd && echo 'systemd' || echo 'init'
la source
Pour
systemd
:la source
Ma solution: vérifiez la commande en cours d'exécution en tant que processus avec l'ID 1.
Pour le moment, je n'ai accès qu'aux machines Init et SystemD. Je ne peux donc pas dire comment Upstart ou macOS (OS X) seront détectés, mais je vais continuer à chercher.
la source
la source