Вопрос или проблема
Это может иметь большее отношение к обнаружению операционных систем, но мне конкретно нужно определить init-систему, используемую в настоящее время в системе.
Fedora 15 и Ubuntu теперь используют systemd, Ubuntu раньше использовала Upstart (долгое время по умолчанию до 15.04), в то время как другие используют вариации System V.
Я пишу приложение, которое должно быть кроссплатформенным демоном. Init-скрипты динамически генерируются на основе параметров, которые можно передать при настройке.
Что бы я хотел сделать, так это генерировать скрипт только для той init-системы, которую они используют. Таким образом, скрипт установки можно запустить без параметров от имени root, и демон можно “установить” автоматически.
Это то, что я придумал:
- Искать systemd, upstart и т.д. в /bin
- Сравнить /proc/1/comm с systemd, upstart и т.д.
- Спросить у пользователя
Какой будет лучший кроссплатформенный способ сделать это?
Немного связано, Могу ли я рассчитывать, что bash будет в большинстве *nix или это зависит от дистрибутива/ОС?
Целевые платформы:
- Mac OS
- Linux (все дистрибутивы)
- BSD (все версии)
- Solaris, Minix и другие *nix
Я тоже сталкивался с этой проблемой и решил провести некоторые тесты. Полностью согласен с тем, что нужно создавать пакеты для каждого дистрибутива отдельно, но иногда есть практические проблемы, которые это предотвращают (не в последнюю очередь нехватка рабочей силы).
Так что для тех, кто хочет “определять автоматически”, вот что я выяснил на ограниченном наборе дистрибутивов (подробнее ниже):
- Определить upstart можно следующим образом:
[[ `/sbin/init —version` =~ upstart ]] && echo yes || echo no
- Определить systemd можно следующим образом:
[[ `systemctl` =~ -.mount ]] && echo yes || echo no
- Определить sys-v init можно следующим образом:
[[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]] && echo yes
Вот мои эксперименты с помощью следующей командной строки:
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
на инстансах ec2 (включаю id AMI us-east):
- ArchLinux: использует systemd (с 2012.10.06)
- CentOS6.4 ami-52009e3b: использует upstart
- CentOS7 ami-96a818fe: использует systemd
- Debian 6 ami-80e915e9: использует sysv-init
- Debian 7.5 ami-2c886c44: использует sysv-init
- Debian 7.6 GCE container-vm: использует sysv-init
- RHEL 6.5 ami-8d756fe4: использует upstart
- SLES 11 ami-e8084981: использует sysv-init
- Ubuntu 10.04 ami-6b350a02: использует upstart
- Ubuntu 12.04 ami-b08b6cd8: использует upstart
- Ubuntu 14.04 ami-a427efcc: использует upstart
- Ubuntu 14.10 и новые версии: использует systemd
- AWS linux 2014.3.2 ami-7c807d14: использует upstart
- Fedora 19 ami-f525389c: использует systemd
- Fedora 20 ami-21362b48: использует systemd
Для ясности: я не утверждаю, что это безошибочно!, почти наверняка это не так. Также обратите внимание, что для удобства я использую регулярные выражения bash, которые доступны не везде. На данный момент этого достаточно для меня. Однако, если вы обнаружите дистрибутив, где это не работает, пожалуйста дайте знать, и я постараюсь исправить это, если есть EC2 AMI, который воспроизводит проблему…
На второй вопрос ответ нет, и вам следует ознакомиться с ресурсами для переносимого программирования на shell.
Что касается первой части – в первую очередь, вам нужно быть осторожным. Я бы сказал, проведите несколько тестов, чтобы убедиться – потому что тот факт, что кто-то действительно установил systemd (например), не означает, что он действительно используется по умолчанию как init. Также, просмотр /proc/1/comm может ввести в заблуждение, потому что некоторые установки различных init-программ могут автоматически делать /sbin/init символической ссылкой или даже переименованной версией их главной программы.
Возможно, наиболее полезным будет посмотреть на тип init-скриптов – потому что именно их вы будете создавать, независимо от того, что их запускает.
Кстати, вы можете также взглянуть на OpenRC, который стремится предоставить структуру init-скриптов, совместимую как с системами Linux, так и с BSD.
Использование процессов
Просмотр вывода из нескольких команд ps, которые могут обнаруживать различные версии systemd и upstart, которые могут быть составлены таким образом:
upstart
$ ps -eaf|grep ‘[u]pstart’root 492 1 0 Jan02 ? 00:00:00 upstart-udev-bridge —daemonroot 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 20root 343 1 0 07:28 ? 00:00:03 /usr/lib/systemd/systemd-journaldroot 367 1 0 07:28 ? 00:00:00 /usr/lib/systemd/systemd-udevdroot 607 1 0 07:28 ? 00:00:00 /usr/lib/systemd/systemd-loginddbus 615 1 0 07:28 ? 00:00:13 /bin/dbus-daemon —system —address=systemd: —nofork —nopidfile —systemd-activation
Обращение внимания на имя процесса с PID #1 также может пролить свет на то, какая init-система используется. На Fedora 19 (которая использует systemd, например:
UID PID PPID C STIME TTY TIME CMDroot 1 0 0 07:27 ? 00:00:03 /usr/lib/systemd/systemd —switched-root —system —deserialize 20
Обратите внимание, что это не init. На Ubuntu с Upstart это всё ещё /sbin/init.
$ ps -efa|grep initroot 1 0 0 Jan02 ? 00:00:03 /sbin/init
ПРИМЕЧАНИЕ: Но используйте это с осторожностью. Нет ничего, что утверждает, что определенная используемая init-система на данном дистрибутиве должна иметь systemd как PID #1.
общий
$ (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
Посмотрите на процессы с ppid 1 (дочерние процессы init-процесса). (Некоторые из) имён дочерних процессов могут указать, какая init-система используется.
Файловая система
Если вы опросите исполняемый файл init, вы сможете получить некоторую информацию из него, просто проанализировав вывод команды —version. Например:
upstart
$ sudo /sbin/init —versioninit (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 MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE.
systemd
$ type initinit is /usr/sbin/init
ПРИМЕЧАНИЕ: Тот факт, что init не в его стандартном месте, немного намекает/подсказывает. На системах sysvinit он всегда располагается в /sbin/init.
sysvinit
$ type initinit is /sbin/init
Также это:
$ sudo init —versioninit: invalid option — -Usage: init 0123456SsQqAaBbCcUu
Выводы
Кажется, нет одного способа сделать это, но вы можете сформулировать набор проверок, который позволит с высокой степенью уверенности определить, какую init-систему вы используете.
Это не так эффективно, но, кажется, работает.
strings /sbin/init | grep -q «/lib/systemd» && echo SYSTEMDstrings /sbin/init | grep -q «sysvinit» && echo SYSVINITstrings /sbin/init | grep -q «upstart» && echo UPSTART
Это выведет больше строк, если будет найдено несколько совпадений строк, что может быть интерпретировано как “Не могу угадать”. Строки, используемые в grep, могут быть слегка модифицированы, но при тестировании на следующих ОС я всегда получил одну строку.
- RHEL 6.4 [UPSTART]
- RHEL ES 4 (Nahant Update 7) [SYSVINIT]
- Ubuntu 16.04.1 LTS [SYSTEMD]
- Ubuntu 14.04.2 LTS [UPSTART]
- Fedora release 23 (онлайн оболочка) [SYSTEMD]
- Debian GNU/Linux 7 (онлайн оболочка) [SYSTEMD]
- Centos 7.6 (VM) [SYSTEMD]
Более упрощенный подход того же решения (но он останавливается на первом совпадении)
strings /sbin/init | awk ‘match($0, /(upstart|systemd|sysvinit)/) { print toupper(substr($0, RSTART, RLENGTH));exit; }’
Обновление:
Как отмечает KCGD, в многих системах strings не установлен. Поэтому более портативной альтернативой может быть:
cat /sbin/init | awk ‘match($0, /(upstart|systemd|sysvinit)/) { print toupper(substr($0, RSTART, RLENGTH));exit; }’ 2> /dev/null
Иногда это так просто, как использование ls :
$ ls -l /sbin/initlrwxrwxrwx 1 root root 20 июн 25 12:04 /sbin/init -> /lib/systemd/systemd
Я думаю, если /sbin/init не является символической ссылкой, вам придется проверить дальнейшие предложения в других ответах.
У меня была такая же проблема, и я провел много тестов на некоторых машинах RedHat/CentOS/Debian/Ubuntu/Mint. Это то, что у меня получилось, с хорошими результатами.
- Найдите имя исполняемого файла с PID 1:
ps -p 1
Если это systemd или Upstart, проблема решена. Если это “init”, это может быть символической ссылкой или чем-то иным, чем явное имя. Идите дальше.
- Найдите реальный путь к исполняемому файлу (работает только от имени root):
ls -l `which init`
If init — это символическая ссылка на Upstart или systemd, проблема решена. В противном случае почти наверняка у вас есть SysV init. Но это может быть неправильно названный исполняемый файл. Идите дальше.
- Найдите пакет, который предоставляет исполняемый файл. К сожалению, это зависит от дистрибутива:
dpkg-query -S (реальный путь к исполняемому файлу) # Debian rpm -qf (реальный путь к исполняемому файлу) # RedHat
Затем, если вы хотите это скриптовать (наиболее забавная часть, по моему мнению), вот мои однострочные команды (выполнять от имени 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
Также проверка дескрипторов файлов может помочь. И это от запускаемого init (в данный момент Debian stretch позволяет иметь установленные несколько init-систем) 🙂
$ ls -l /proc/1/fd |grep systemdlrwx—— 1 root root 64 сен 14 13:56 25 -> /run/systemd/initctl/fifolr-x—— 1 root root 64 сен 14 13:56 6 -> /sys/fs/cgroup/systemd$ ls -l /proc/1/fd |grep /run/initctl # sysvinitlrwx—— 1 root root 64 сен 14 14:04 10 -> /run/initctl$ ls -l /proc/1/fd |grep upstartl-wx—— 1 root root 64 сен 13 16:09 13 -> /var/log/upstart/mysql.log.1 (удалено)l-wx—— 1 root root 64 сен 13 16:09 9 -> /var/log/upstart/dbus.log.1 (удалено)$ ls -l /proc/1/fd # busyboxtotal 0lrwx—— 1 root root 64 янв 1 00:00 0 -> /dev/consolelrwx—— 1 root root 64 янв 1 00:00 1 -> /dev/consolelrwx—— 1 root root 64 янв 1 00:00 2 -> /dev/console
Вероятно, более безопасный способ проверки на busybox будет проверить /proc/1/exe, так как busybox обычно использует символические ссылки:
$ ls -l /proc/1/exe lrwxrwxrwx 1 root root 0 янв 1 00:00 /proc/1/exe -> /bin/busybox
Так что проверка может быть следующей:
{ 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 «неизвестная init»
- Для этого существуют дистрибутивно-специфичные пакеты. Установка программного обеспечения подразумевает гораздо больше, чем просто определение init-системы. Многие дистрибутивы используют SysVinit, но не все из них пишут свои init-скрипты одинаково. Правильный способ решения этого – включить все различные варианты и затем упаковать это с использованием спецификационных файлов с дистрибутивно-специфичными именами зависимостей для дистрибутивов на базе rpm, deb-файлов для систем на базе apt и т.д. Почти все дистрибутивы имеют какой-то вид пакетов спецификацией, которая включает зависимости, скрипты, init-скрипты и т.д. Не изобретайте колесо заново здесь.
- Нет. Что возвращает нас к пункту 1. Если вам нужен bash, это должно быть зависимостью. Вы можете указать это как часть ваших настроечных скриптов, но это также должно быть в описаниях пакетов.
Редактировать: Используйте флаги на вашем настройщике, такие как —with upstart или —without sysvinit. Выберите разумный стандарт, тогда скрипты, которые упаковывают ваше программное обеспечение для других дистрибутивов, смогут выбрать, как выполнить это с другими опциями.
На Gentoo, взгляните на pid 1:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.0 4216 340 ? Ss 2013 0:57 init [3]
Если это init, то init-система – OpenRC. Если это systemd, то init-система – systemd.
Вы можете определить Gentoo с помощью [ -f /etc/gentoo-release ].
Другой метод на Gentoo – использовать profile-config show, который покажет, какой профиль по умолчанию используется. Все профили, кроме двух, оканчивающихся на /systemd, используют init OpenRC. Имейте в виду, что эти профили только представляют собой по умолчанию, и возможно, что пользователь предпринял шаги, чтобы переопределить этот стандарт, и это может не отражать init-менеджер, фактически используемый.
Для systemd:
if [[ `systemctl is-system-running` =~ running ]]; then echo using systemd; fi
На debian /sbin/init является символической ссылкой на ваш стандартный init, поэтому
ls -l /sbin/init
даст вам информацию, которую вы ищете.
$ ls -l /sbin/init lrwxrwxrwx 1 root root 20 ноя 18 13:15 /sbin/init -> /lib/systemd/systemd
Простое использование greping по процессу с PID 1 расскажет вам:
strings /proc/1/exe |grep -q sysvinitstrings /proc/1/exe |grep -q systemd
Не знаю про другие системы, кроме Debian (wheezy) /или Ubuntu (14.10.), но я тестирую такие вопросы с помощью простого file команды.
file /sbin/init
даёт это:
/sbin/init: символическая ссылка на ‘upstart’
Системы Debian с systemd (например, sid) показывают это:
# file /sbin/init /sbin/init: символическая ссылка на /lib/systemd/systemd
Это действительно легко для некоторых init-систем. Для systemd:
test -d /run/systemd/system
для upstart:
initctl —version | grep -q upstart
для всего остального вы просто можете предположить, основываясь на дистрибутиве (launchd на OS X, sysvinit на Debian, OpenRC на Gentoo).
Вот bash-скрипт для выполнения детектирования. В данный момент он проверяет только upstart и systemd, но его легко расширить. Я взял этот код из кода, который я добавил в скрипт установки драйвера DisplayLink.
detect_distro(){ # init процесс — это 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}
Существует много подводных камней совместимости при тестировании systemd vs initd. Это действительно работает на OpenSuSE 42.1: ps —pid 1 | grep -q systemd && echo ‘systemd’ || echo ‘init’
Моё решение: проверьте команду, работающую в процессе с идентификатором 1.
case `cat /proc/1/comm` in init) echo Init ;; systemd) echo SystemD ;; # добавьте здесь другие шаблоны *) echo «unknown: ‘`cat /proc/1/comm`'» ;;esac
На данный момент у меня есть доступ только к машинам Init и SystemD, так что я не могу сказать, как будет обнаружено Upstart или macOS (OS X), но я продолжу поиск.
Я бы использовал pstree и просто нашёл бы его корень. На моих системах Ubuntu, Arch и Fedora (к сожалению, все используют systemd для init), запуск pstree даёт мне следующий вывод головы:
systemd-+-GUIPool-+-calibre-paralle | `-8*[{GUIPool}] |-MainThread-+-Privileged Cont—29*[{Privileged Cont}] | |-Web Content—30*[{Web Content}] | |-Web Content—32*[{Web Content}]
- Так что, как простое решение с использованием pstree, head и cut, которые предустановлены на большинстве систем, я бы запустил pstree | head -n 1 | cut -d «-» -f 1,1
Он вывел нужную строку “systemd” на всех трёх ОС, которые я тестировал. - В качестве альтернативы, вы могли бы запустить что-то вроде
pstree | head -n 1 | ([[ $(grep systemd) ]] && echo systemd) || ([[ $(grep upstart) ]] && echo upstart) || ([[ $(grep sysvinit) ]] && echo sysvinit)
check(){ if hash systemctl 2>/dev/null; then echo «есть systemd» fi if hash initctl 2>/dev/null; then echo «есть upStart» fi if [ -f «/etc/inittab»]; then echo «есть systemV» fi}
Как насчет этого :
strings $(ps -p 1 o cmd= | cut -d» » -f1) | egrep -o «upstart|sysvinit|systemd» | head -1
Тестировалось только на системах, к которым у меня есть доступ: Ubuntu и SailfishOS.
Моё окончательное решение.
Так как upstart кажется мёртвым и я не нахожу его нигде, я не могу протестировать, что будет, если я вызову ps -C upstart на хосте на основе upstart.
Попытки различных ps 1 определённо не были эффективными на всех моих тестируемых хостах…
Моя цель, наконец:
if ps -C systemd | grep -q ‘^ *1 ‘ ;then echo Эта система использует systemdelse echo Эта система использует initfi
Проверьте, ли моя система systemd доступна
Для тех, кто задается вопросом, есть ли у вашей системы install systemd, а не если она была загружена через systemd, это самые простые команды, которые я мог придумать. Я использую это, чтобы проверить, успешно ли моя пользовательская встраиваемая плата Linux получила systemd от Buildroot:
# лучший метод: проверьте версию systemd-runsystemd-run —version# или: ищите любые файлы или папки «systemd» на вашем компьютереfind / | grep -i systemd | sort -V# или: ищите файлы «systemd» в /usr/binfind /usr/bin | grep -i systemd | sort -V
Для моей платы я получаю следующий вывод:
Первая команда:
# systemd-run —versionsystemd 244 (244)-PAM -AUDIT -SELINUX -IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS -ACL -XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 -IDN -PCRE2 default-hierarchy=hybrid
В моем systemd.mk makefile в Buildroot указано SYSTEMD_VERSION = 244.3, поэтому это имеет смысл.
Вторая команда:
Она слишком длинная, чтобы мне хотелось копировать/вставлять все это, но она показывает записи в /usr/lib/systemd, /usr/bin/systemd* и т.д.
Третья команда:
# find /usr/bin | grep -i systemd | sort -V/usr/bin/systemd-analyze/usr/bin/systemd-ask-password/usr/bin/systemd-cat/usr/bin/systemd-cgls/usr/bin/systemd-cgtop/usr/bin/systemd-delta/usr/bin/systemd-detect-virt/usr/bin/systemd-escape/usr/bin/systemd-id128/usr/bin/systemd-machine-id-setup/usr/bin/systemd-mount/usr/bin/systemd-notify/usr/bin/systemd-nspawn/usr/bin/systemd-path/usr/bin/systemd-run/usr/bin/systemd-socket-activate/usr/bin/systemd-stdio-bridge/usr/bin/systemd-tty-ask-password-agent/usr/bin/systemd-umount
Это список, из которого я нашел исполняемый файл systemd-run. Я просто предположил, что выполнение systemd-run —version может сработать, и это сработало!
Смотрите также
- Super User: Как узнать, использую ли я systemd на Linux?
- Удобный способ проверить, используется ли система systemd или sysvinit в BASH?
Следуя вопросу OP, вот поддержка для: macOS, Linux (systemd) и OpenRC (Linux, *BSDs, производные SunOS). Не стесняйтесь расширять этот ответ поддержкой для других init-систем:
#!/bin/shif [ -z «${UNAME+x}» ]; then UNAME=»$(uname)»fiif [ -z «${INIT_SYS+x}» ]; then if [ -f ‘/bin/launchctl’ ]; then # https://en.wikipedia.org/wiki/Launchd export INIT_SYS=’launchd’ elif [ -f ‘/sbin/openrc-run’ ]; then # https://en.wikipedia.org/wiki/OpenRC export INIT_SYS=’openrc’ else case «${UNAME}» in ‘Linux’) if [ ! -f ‘/sbin/init’ ]; then proc_comm=»$(stat — «$(which — «$(cat — ‘/proc/1/comm’)»)» | awk ‘NR==1{ print $NF }’)» case «${proc_comm}» in *’/bin/bash’|’dash’|’bash’) >&2 printf ‘Нет установки системы инициализацииn’ exit 2 ;; *) >&2 printf ‘Не удается определить систему инициализации из «%s»n’ «${proc_comm}» exit 2 ;; esac elif [ -f ‘/etc/inittab’ ]; then case «$(grep -F ‘::sysinit:’ ‘/etc/inittab’ | awk -F’:/’ ‘{print «/» $2}’ | awk ‘{print $1}’)» in ‘/sbin/openrc’|*’/openrc’) # https://en.wikipedia.org/wiki/OpenRC export INIT_SYS=’openrc’ ;; *) >&2 printf ‘Не удается определить систему инициализацииn’ exit 2 ;; esac else case «$(stat — «$(which — «$(cat — ‘/proc/1/comm’)»)» | awk ‘NR==1{ print $NF }’)» in # case «$(stat — ‘/sbin/init’ | awk ‘NR==1{ print $NF }’)» in ‘busybox’|*’/busybox’) # https://en.wikipedia.org/wiki/BusyBox export INIT_SYS=’busybox’ ;; *’/systemd’) # https://en.wikipedia.org/wiki/Systemd export INIT_SYS=’systemd’ ;; *) >&2 printf ‘Не удается определить систему инициализацииn’ exit 2 ;; esac fi ;; *) >&2 printf ‘TODO: *BSD, minix, SunOS, illumos, &etc.n’ exit 2 ;; esac fifi
Ответ или решение
Определение системы инициализации в Unix-подобных операционных системах является востребованной задачей, особенно при разработке приложений, которые должны работать кросс-платформенно. В современных операционных системах можно встретить несколько систем инициализации, таких как systemd, Upstart и System V (SysV). Каждая из них имеет свои особенности настройки и управления системными службами. Поскольку вы разрабатываете демона, который должен быть установлен на различных дистрибутивах, важно корректно определить используемую систему инициализации для генерации соответствующих скриптов.
Теория
Система инициализации представляет собой ключевой компонент в процессе загрузки операционной системы. Она отвечает за запуск и управление службами и процессами после загрузки ядра. Исторически сложилось, что на Unix-подобных системах применялась система SysV, основанная на скриптах инициализации, помещенных в стандартные каталоги (/etc/init.d). Однако многие современные дистрибутивы, включая Fedora и Ubuntu, перешли на использование systemd — более современной системы инициализации, которая предоставляет расширенные возможности управления зависимостями между службами и ускоряет время загрузки.
Кроме того, некоторое время в Ubuntu использовалась система Upstart, разработанная для улучшенной обработки событий и контроля служб. Хотя systemd занимает доминирующее положение, знание способов определения текущей системы инициализации остается актуальным для поддержки более старых и специфичных дистрибутивов.
Пример
Рассмотрим несколько подходов для определения системы инициализации:
- Проверка процесса с идентификатором 1: В Unix-подобных системах процесс загрузки всегда имеет PID 1. Командой ps -p 1 -o comm= можно узнать, какой процесс использует систему инициализации. Например, если результат systemd, то используется systemd.
- Анализ символьной ссылки: В некоторых системах /sbin/init является символьной ссылкой на реальный бинарник системы инициализации. Через команду ls -l /sbin/init можно определить целевую систему.
- Запрос версий: Можно вызвать версию предполагаемых систем инициализации. Например, если systemctl —version не возвращает ошибку, значит, systemd присутствует в системе.
Применение
Теперь, когда мы понимаем методы, применим их в контексте многообразия Unix-подобных систем:
- Linux на базе systemd: Многие современные дистрибутивы, такие как Fedora и RHEL, используют systemd. Здесь, как правило, /sbin/init будет являться символьной ссылкой на /lib/systemd/systemd. Вы также можете запрашивать статус с помощью команды systemctl.
- Старые версии Ubuntu или Linux Mint: В таких системах может использоваться Upstart. Скрипт /sbin/init в этом случае может быть символьной ссылкой на Upstart.
- Традиционные Unix-системы и меньшие дистрибутивы: Здесь может использоваться либо оригинальная системная V-инициализация, либо ее производные. Проверка наличия файлов, таких как /etc/inittab, может быть полезна.
Дополнительно
Также стоит помнить о наличии OpenRC, используемой в дистрибутивах Gentoo и Alpine Linux. В этом случае полезно проверить наличие специфичных утилит, таких как rc-service.
Заключение
Определение системы инициализации имеет важное значение для настройки демонов в различных Unix-подобных системах. Несмотря на тенденцию, когда большинство дистрибутивов переходят на systemd, важно понимать различные системы инициализации для обеспечения совместимости и надежной работы программного обеспечения на разных платформах. Более того, понимание этих различий помогает в лучшей настройке и управлении поведением приложений в зависимости от дистрибутива и среды выполнения.