Это может иметь большее отношение к обнаружению операционных систем, но мне особенно нужна система инициализации, используемая в настоящее время в системе.
Fedora 15 и Ubuntu теперь используют systemd, Ubuntu раньше использовал Upstart (долгое время по умолчанию до 15.04), в то время как другие используют варианты System V.
У меня есть приложение, которое я пишу, чтобы стать кроссплатформенным демоном. Сценарии инициализации генерируются динамически на основе параметров, которые могут быть переданы при конфигурировании.
То, что я хотел бы сделать, это только создать сценарий для конкретной системы инициализации, которую они используют. Таким образом, скрипт установки может быть запущен без параметров в качестве пользователя root, а демон может быть автоматически «установлен».
Вот что я придумал:
- Поиск systemd, upstart и т. Д. В / bin
- Сравните / proc / 1 / comm с systemd, upstart и т. Д.
- Спросите пользователя
Каков наилучший кроссплатформенный способ сделать это?
Вид связанных, Могу ли я рассчитывать на то, что bash будет работать на большинстве * nix или это зависит от дистрибутива / ОС?
Целевые платформы:
- Mac OS
- Linux (все дистрибутивы)
- BSD (все версии)
- Solaris, Minix и другие * nix
источник
ps -p 1 -o command
(печатает путь к текущемуinit
). В Arch Linux и Fedora (IIRC) это символическая ссылка наsystemd
двоичный файл (вероятно, одинаковый во всехsystemd
системах). Наupstart
,init --help
будет печатать информацию об использовании, и на моей коробкеupstart
упоминается, где говорится, кому по электронной почте. На FreeBSD (sysV) это вернет ошибку. Могут быть похожие подсказки в других системах, но с тех пор, как я задал этот вопрос, я решил просто создать их для всех платформ и создать отдельные пакеты для каждой.sudo lsof -a -p 1 -d txt
может дать еще более точные результаты.ps
может напечатать произвольное имя, тогда как сlsof
вами получится реальный путь к исполняемому файлу. (См. Мой вопрос unix.stackexchange.com/questions/102453/… )Ответы:
На второй вопрос ответ - нет, и вы должны взглянуть на Ресурсы для программирования переносимых оболочек .
Что касается первой части - прежде всего, вам, безусловно, нужно быть осторожным. Я бы сказал, чтобы выполнить несколько тестов, чтобы убедиться - потому что тот факт, что кто-то действительно установил systemd (например), не означает, что он действительно используется по умолчанию
init
. Кроме того, рассмотрение/proc/1/comm
может вводить в заблуждение, потому что некоторые установки различных программ инициализации могут автоматически сделать/sbin/init
символическую ссылку жесткой или даже переименованной версией их основной программы.Возможно, самой полезной вещью может быть просмотр типа сценариев инициализации - потому что это то, что вы на самом деле будете создавать, независимо от того, что их запускает.
В качестве примечания вы можете также взглянуть на OpenRC, целью которого является предоставить структуру сценариев инициализации, совместимых как с Linux, так и с системами BSD.
источник
/etc/init
, как это делает systemd/etc/systemd
. Если бы у меня был такой сценарий, это могло бы занять некоторое время. О, и спасибо за ссылку BTW для программирования портативной оболочки./etc/rc.d/
or/etc/init.d/
). И вы должны правильно настроить вашу программу во время установки, чтобы использовать структуру, которая используется в данной системе.Я сам вошел в эту проблему и решил сделать несколько тестов. Я полностью согласен с ответом, что каждый пакет должен быть упакован отдельно, но иногда есть практические проблемы, которые мешают этому (не в последнюю очередь человеческие ресурсы).
Так что для тех, кто хочет «автоматически определять», вот что я обнаружил на ограниченном наборе дистрибутивов (подробнее ниже):
Вы можете сказать выскочку из:
Вы можете сказать systemd из:
Вы можете сказать sys-v init из:
Вот мои эксперименты со следующей командной строкой:
в случае с ec2 (я включаю идентификатор AMI с восточной стороны США):
Просто чтобы прояснить: я не утверждаю, что это надежно! почти наверняка это не так. Также обратите внимание, что для удобства я использую совпадения регулярных выражений bash, которые не везде доступны. Выше это достаточно хорошо для меня прямо сейчас. Однако, если вы обнаружите дистрибутив, где он не работает, пожалуйста, дайте мне знать, и я постараюсь это исправить, если есть EC2 AMI, который воспроизводит проблему ...
источник
/run/systemd/system
.launchd
, систему инициализации в macOS:[[ $(ps 1) =~ 'launchd' ]] && echo yes || echo no
протестировано на MacBookPro, macOS Sierra Версия 10.12if [ -h /sbin/init -a $(readlink /sbin/init | grep busybox | wc -l) -gt 0 ]; then echo yes; else echo no; fi
Использование процессов
Посмотрим на выходные данные пары
ps
команд, которые могут обнаружить различные версииsystemd
&upstart
, которые могут быть созданы следующим образом:выскочка
Systemd
Обращение к названию процесса, который называется PID # 1, также может пролить свет на то, какая система инициализации используется. На Fedora 19 (которая использует
systemd
, например:Обратите внимание, это не так
init
. На Ubuntu с Upstart это все еще/sbin/init
.ПРИМЕЧАНИЕ: но используйте это с некоторой осторожностью. В камне нет ничего, что говорило бы о том, что конкретная система инициализации, используемая в данном дистрибутиве , должна иметь
systemd
PID # 1.общий
Посмотрите на процессы с ppid 1 (потомки процесса init). (Некоторые из) имен дочерних процессов могут указывать на используемую систему инициализации.
Файловая система
Если вы запрашиваете
init
исполняемый файл, вы также можете получить от него некоторую информацию. Просто разбирая--version
вывод. Например:выскочка
Systemd
ПРИМЕЧАНИЕ. Тот факт, что
init
он не находится в его стандартном расположении, является подсказкой. Он всегда находится в/sbin/init
системах sysvinit.Sysvinit
Также это:
Выводы
Так что, похоже, нет единственного способа сделать это, но вы могли бы сформулировать набор проверок, которые бы точно указывали, какую систему инициализации вы используете с достаточно высокой степенью достоверности.
источник
pgrep systemd >/dev/null && echo init system: systemd
/usr/lib/systemd/systemd
если используется systemd, это ложное предположение. Например, в моей системе PID # 1/sbin/init
(я использую systemd). Это зависит от распределения.pgrep systemd >/dev/null && echo init system: systemd -> init system: systemd
иtype init -> init is /sbin/init
Не так эффективно, но я, кажется, работает.
Он напечатает больше строк, если будет найдено более одной строки, что можно перевести как «Не могу угадать». Строки, используемые в grep, могут быть немного изменены, но при тестировании в следующей ОС я всегда получал одну строку.
Более упрощенный подход к тому же решению (но он останавливается при первом совпадении)
источник
Иногда это так же просто, как использовать
ls
:Я думаю, если
/sbin/init
это не символическая ссылка, вам придется проверить дальнейшие предложения в других ответах.источник
Для этого предназначены специальные дистрибутивные пакеты. Правильная установка программного обеспечения - это гораздо больше, чем просто обнаружение системы инициализации. Многие дистрибутивы используют SysVinit, но не все пишут свои сценарии инициализации одинаково. Правильный способ решить эту проблему - включить все различные варианты, а затем объединить их, используя файлы спецификаций с именами зависимых от дистрибутивов зависимостей для дистрибутивов rpm, файлы deb для систем на основе apt и т. Д. Почти во всех дистрибутивах есть какая-то спецификация пакета, которую вы Можно написать, что включает в себя зависимости, сценарии, сценарии инициализации и т. д. Не изобретайте колесо здесь.
Нет. Что возвращает нас к 1. Если вам нужен bash, это должна быть зависимость. Вы можете указать эту проверку как часть ваших скриптов configure, но она также должна быть в описании пакета.
Редактировать: Используйте флаги в вашем скрипте конфигурации, такие как
--with upstart
или--without sysvinit
. Выберите разумное значение по умолчанию, тогда сценарии, которые упаковывают ваше программное обеспечение для других дистрибутивов, могут выбрать запуск с другими параметрами.источник
В Gentoo взгляните на pid 1:
Если это так
init
, то система инициализации естьOpenRC
. Если это такsystemd
, то система инициализации естьsystemd
.Вы можете обнаружить Gentoo с помощью
[ -f /etc/gentoo-release ]
.В Gentoo используется другой метод
profile-config show
, который покажет, какой профиль по умолчанию используется. Все профили, кроме двух, заканчивающихся на / systemd, используют инициализацию OpenRC. Имейте в виду, что они являются только репрезентативными по умолчанию, и вполне возможно, что пользователь предпринял шаги для отмены этого по умолчанию и может не указывать на фактически используемый менеджер инициализации.источник
p
опцию (идентичную-p
и--pid
) для выбора с помощью PID. Приведенный выше фрагмент фактически является выходом дляps u --pid 1
.На debian / sbin / init есть символическая ссылка на ваш init по умолчанию, так
даст вам информацию, которую вы ищете.
источник
init
можно установить на Ubuntu 14.04?Простой переход к процессу с PID 1 скажет вам:
источник
proc
файловая система ...Также может помочь проверка файловых дескрипторов. И это из фактического запуска init (Debian stretch в настоящее время позволяет устанавливать больше систем инициализации) :-)
Вероятно, более безопасный способ проверить занятость будет
check /proc/1/exe
, так как busybox обычно использует символические ссылки:Так что проверка может быть:
источник
/run/systemd/system
.Не знаю о других системах, кроме Debian (wheezy) / или Ubuntu (14.10.), Но я тестирую такие проблемы с помощью простой старой
file
команды.дать это:
Системы Debian с
systemd
(например, sid) показывают это:источник
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
означает, что мы используем SYSV здесь. Вывод для Ubuntu показан в моем ответе.file /sbin/init
вернул «исполняемый файл» на всех системах. Он также возвращает то же самое на CentOS 5.8, SLES 10, Ubuntu 8.04, практически в каждой системе, в которую я могу попасть. Итак, насколько я могу судить, это даже не работает для выскочки и Ubuntu.У меня тоже была такая же проблема, и я провел много тестов на некоторых машинах RedHat / CentOS / Debian / Ubuntu / Mint. Это то, что я закончил, с хорошими результатами.
Найдите имя исполняемого файла с PID 1:
Если это systemd или Upstart, проблема решена. Если это «init», это может быть символическая ссылка или что-то иное, чем предварительное имя. Преуспевать.
Найдите реальный путь к исполняемому файлу (работает только как root):
Если
init
есть символическая ссылка на Upstart или systemd, проблема решена. В противном случае это почти наверняка у вас есть SysV init. Но это может быть ошибочно названный исполняемый файл. Преуспевать.Найдите пакет, который предоставляет исполняемый файл. К сожалению, это зависит от дистрибутива:
Затем, если вы хотите написать это (самая забавная часть, ИМХО), это мои однострочники (запускаются с правами root):
источник
init --version
чтобы получить информацию.Это действительно легко для некоторых систем инициализации. Для systemd:
для выскочки:
для всего остального, вы можете просто предположить, основываясь на дистрибутиве (запущенный на OS X, sysvinit на Debian, OpenRC на Gentoo).
источник
Вот скрипт bash для обнаружения. На данный момент он проверяет только upstart и systemd, но его легко расширить. Я взял это из кода, который я внес в скрипт установки драйвера DisplayLink .
источник
/proc
связывает это с Linux (если он настроен соответствующим образом) и одним или двумя другими - это, безусловно, далеко не универсально.При тестировании systemd vs initd существует множество ошибок совместимости. Это на самом деле работает на OpenSuSE 42.1:
ps --pid 1 | grep -q systemd && echo 'systemd' || echo 'init'
источник
Для
systemd
:источник
Мое решение: проверьте команду, запущенную как процесс, с ID 1.
На данный момент у меня есть доступ только к компьютерам Init и SystemD, поэтому я не могу сказать, как будет обнаружен Upstart или macOS (OS X), но я продолжу поиск.
источник
источник