쉘을 사용하여 초기화 시스템 감지


90

이것은 운영 체제 감지와 더 관련이있을 수 있지만 특히 시스템에서 현재 사용중인 init 시스템이 필요합니다.

Fedora 15와 Ubuntu는 이제 systemd를 사용하고, Ubuntu는 Upstart (15.04까지 오랜 시간 기본값)를 사용했지만 다른 시스템은 System V의 변형을 사용합니다.

크로스 플랫폼 데몬으로 작성중인 응용 프로그램이 있습니다. init 스크립트는 configure에 전달 될 수있는 매개 변수를 기반으로 동적으로 생성됩니다.

내가하고 싶은 것은 그들이 사용하는 특정 init 시스템에 대한 스크립트 만 생성하는 것입니다. 이런 식으로 설치 스크립트를 루트없이 매개 변수없이 합리적으로 실행할 수 있으며 데몬을 자동으로 "설치"할 수 있습니다.

이것이 내가 생각해 낸 것입니다.

  • / bin에서 systemd, upstart 등 검색
  • / proc / 1 / comm을 systemd, upstart 등과 비교하십시오.
  • 사용자에게 물어보세요

이 작업을 수행하는 가장 좋은 교차 / 플랫폼 방법은 무엇입니까?

관련의 종류는, 내가 * nix에서 스크립트의 대부분에있을 배쉬에 따라 달라질 수 있습니다하거나 유통 / OS 종속인가?

대상 플랫폼 :

  • 맥 OS
  • 리눅스 (모든 배포판)
  • BSD (모든 버전)
  • Solaris, Minix 및 기타 * nix

1
내 두 센트를 추가하기 위해 bash는 기본적으로 FreeBSD에 설치되지 않습니다.
Chinmay Kanchi

@ tjameson, 더 직접적인 방법을 찾았습니까? 나는 똑같은 것을 찾고 있지만 여기의 대답은 직접적인 대답이 아니라 단지 방향입니다. 특히 1) 검색 할 스크립트 위치 및 2) 여러 개의 시스템이 설치되어있는 경우에 유효한 init 시스템 감지 (bash가 직접 응답 됨).
n611x007

3
@naxa-짧은 답변입니다. 긴 대답, 당신은 꽤 멀리 갈 수 있습니다 ps -p 1 -o command(현재 경로를 인쇄합니다 init). 아치 리눅스와 페도라 (IIRC)에서는 systemd바이너리에 대한 심볼릭 링크입니다 (아마 모든 systemd시스템에서 동일 ). 에 upstart, init --help사용 정보를 인쇄하고 내 상자 upstart에 이메일을 보낼 사람이 언급되어 있습니다. FreeBSD (sysV)에서는 에러를 반환합니다. 다른 시스템에서도 비슷한 단서가있을 수 있지만이 질문을 한 후 모든 플랫폼에 대해 해당 단서를 작성하고 각각에 대해 별도의 패키지를 작성하기로 결정했습니다.
beatgammit

좋은 정보 감사합니다! 나는 sudo lsof -a -p 1 -d txt더 정확한 결과를 줄 수 있다는 것을 배웠습니다 . ps임의의 이름을 인쇄 lsof할 수 있지만 실제 실행 경로는 얻을 수 있습니다. (내 질문 unix.stackexchange.com/questions/102453/… 참조 )
n611x007

1
연결된 질문에 대한 답변이나 의견은 배쉬와 관련이 없습니다. 솔루션은 귀하의 경우에도 적용 가능해야합니다.
Marco

답변:


30

두 번째 질문에 대한 답은 ' 아니오' 이며 이식 가능한 쉘 프로그래밍을위한 참고 자료를 살펴보아야한다 .

첫 번째 부분은-우선, 조심해야합니다. 누군가 (예를 들어) 시스템을 설치 했다는 사실이 그것이 실제로 기본값으로 사용된다는 것을 의미하지 않기 때문에 몇 가지 테스트를 수행 한다고 말하고 싶습니다 . 또한 여러 init 프로그램을 설치 하면 symlink 하드 링크 나 기본 프로그램의 이름이 바뀐 버전을 자동으로 만들 수 있기 때문에 보는 것이 잘못 될 수 있습니다 .init/proc/1/comm/sbin/init

아마도 가장 유용한 것은 init 스크립트 유형을 보는 것입니다. 실행 스크립트에 관계없이 실제로 작성하는 스크립트 유형이기 때문입니다.

참고로 Linux 및 BSD 시스템과 호환되는 init 스크립트 구조를 제공하는 OpenRC 를 살펴볼 수도 있습니다 .


2
"init 스크립트 유형보기"는 무엇을 의미합니까? 종종 서로 다른 init 시스템은 /etc/initsystemd와 같이 스크립트 / 파일을 다른 곳에 넣습니다 /etc/systemd. 내 스크립트를 가져 오려면 시간이 조금 걸릴 수 있습니다. 아, 그리고 휴대용 쉘 프로그래밍을위한 링크 BTW에 감사드립니다.
beatgammit

1
다른 init 스크립트의 유형과 위치 ( /etc/rc.d/또는 같은 /etc/init.d/)를 사용하도록 일부 init 구현을 조정할 수 있다고 말하고 싶습니다 . 그리고 주어진 시스템에서 사용되는 구조를 활용하기 위해 설치시 프로그램 올바르게 조정해야 합니다.
rozcietrzewiacz 1

2
프로그래밍 방식으로 초기화 시스템을 감지하는 신뢰할 수있는 방법이 없다고 말하는가? 사용자가 매개 변수를 전달하는 것이 확실히 안전하지만 사용자가 아무것도 전달하지 않으면 추측하는 가장 좋은 방법은 무엇입니까?
beatgammit

프로그램에 가장 적합한 방법이 무엇인지 잘 모르겠습니다 . 프로그램이 실행되는 시스템에 따라 다릅니다. 분포를 너무 많이 사용하지는 않았지만 관찰 한 내용을 공유하려고 노력했습니다. 그것은 당신이 시도하려고하는 어려운 스크립팅 조각이며 현장에서 약간의 견해를 주려고했습니다. 최종 답변을 직접 보거나 더 많은 힌트를 기다려야합니다.
rozcietrzewiacz 1

모든 도움을 주셔서 감사합니다. 당신은 분명히 올바른 방향으로 나를 가리 켰습니다.
beatgammit

58

나는이 문제를 직접 시작했고 몇 가지 테스트를하기로 결정했습니다. 나는 각 배포판에 대해 개별적으로 패키지해야한다는 대답에 전적으로 동의하지만 때로는 그것을 막는 실질적인 문제가 있습니다 (인력뿐만 아니라).

그래서 "자동 감지"를 원하는 사람들을 위해 제한된 배포판에서 발견 한 내용이 있습니다 (아래 참조).

  • 다음과 같이 시작을 알려줄 수 있습니다.

    [[ `/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 인스턴스 (미국 동부 AMI ID 포함) :

  • ArchLinux : systemd 사용 ( 2012.10.06 부터 )
  • CentOS6.4 ami-52009e3b : 시작 사용
  • CentOS7 AMI-96A818FE : 시스템 사용
  • 데비안 6 ami-80e915e9 : sysv-init 사용
  • 데비안 7.5 ami-2c886c44 : sysv-init 사용
  • 데비안 7.6 GCE 컨테이너 -VM : sysv-init 사용
  • RHEL 6.5 ami-8d756fe4 : 시작 사용
  • SLES 11 ami-e8084981 : sysv-init 사용
  • 우분투 10.04 ami-6b350a02 : upstart 사용
  • 우분투 12.04 ami-b08b6cd8 : upstart 사용
  • 우분투 14.04 ami-a427efcc : upstart 사용
  • 우분투 14.10 이하 : systemd 사용
  • AWS Linux 2014.3.2 ami-7c807d14 : 시작 사용
  • Fedora 19 AMI-F525389C : 시스템 사용
  • Fedora 20 AMI-21362B48 : 시스템 사용

분명하게 : 나는 이것이 바보라고 주장하지 않습니다! 거의 확실하지 않습니다. 또한 편의상 bash regexp 일치를 사용하지만 모든 곳에서 사용할 수는 없습니다. 위의 내용은 지금 당장 충분합니다. 그러나 실패한 배포판을 찾으면 알려주십시오. 문제를 재현하는 EC2 AMI가 있으면 문제를 해결하려고 노력할 것입니다 ...


5
시스템 설명서 ( sd_booted (3) ) 에 따르면 systemd 를 확인하는 올바른 방법은 디렉토리 /run/systemd/system가 있는지 확인 하는 것입니다.
Robie Basak

1
launchdmacOS의 init 시스템 인 이 탐지에 추가 할 것입니다 : [[ $(ps 1) =~ 'launchd' ]] && echo yes || echo nomacOS Sierra 버전 10.12
Tony

busybox를 추가하겠습니다 :if [ -h /sbin/init -a $(readlink /sbin/init | grep busybox | wc -l) -gt 0 ]; then echo yes; else echo no; fi
Astrinus

18

프로세스 사용

ps다양한 버전의 systemd&를 감지 할 수 있는 몇 가지 명령 의 출력을 보면 upstart다음과 같이 제작할 수 있습니다.

건방진 녀석

$ 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

체계적

$ 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

PID # 1 인 프로세스의 이름에주의를 기울이면 init 시스템이 사용되는 프로세스를 잠재적으로 밝힐 수 있습니다. Fedora 19 ( systemd예 :

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

그렇지 않습니다 init. Upstart가있는 Ubuntu에서는 여전히 /sbin/init입니다.

$ ps -efa|grep init
root         1     0  0 Jan02 ?        00:00:03 /sbin/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실행 파일 을 조사하면 정보를 얻을 수도 있습니다. 단순히 --version출력을 구문 분석합니다 . 예를 들면 다음과 같습니다.

건방진 녀석

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

체계적

$ type init
init is /usr/sbin/init

참고 :init 표준 위치에 있지 않은 사실 은 약간의 힌트 / 말입니다 . 항상 /sbin/initsysvinit 시스템에 있습니다.

sysvinit

$ type init
init is /sbin/init

또한 이것 :

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

결론

따라서 한 가지 방법이없는 것처럼 보이지만 사용중인 init 시스템을 정확하게 파악할 수있는 일련의 검사를 공식화 할 수 있습니다.


방법에 대해 :pgrep systemd >/dev/null && echo init system: systemd
마르코

감사합니다. 이것은 내가 찾던 것입니다 : init 시스템을 결정하기 위해 취해야 할 몇 가지 단계.
user369450

1
PID # 1은 /usr/lib/systemd/systemdsystemd를 사용하는 경우 반드시 필요한 것은 아니며 잘못된 가정입니다. 예를 들어 내 시스템에서 PID # 1은 /sbin/init(systemd를 사용합니다)입니다. 배포판에 따라 다릅니다.
Marco

내 kubuntu 15.04 설치에서 systemd와 sysvinit이 모두있는 것으로 보입니다. 몰라 왜 나 그게 무슨 뜻인지, 단지 말을 .. pgrep systemd >/dev/null && echo init system: systemd -> init system: systemdtype init -> init is /sbin/init
dotnetCarpenter

12

그렇게 효율적이지는 않지만 작동하는 것 같습니다.

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

하나 이상의 문자열이 일치하면 더 많은 행을 인쇄하여 "추측 할 수 없음"으로 변환 될 수 있습니다. grep에 사용되는 문자열은 약간 수정 될 수 있지만 다음 os에서 테스트 할 때 항상 한 줄을 얻었습니다.

  • RHEL 6.4 [UPSTART]
  • RHEL ES 4 (Nahant 업데이트 7) [SYSVINIT]
  • 우분투 16.04.1 LTS [SYSTEMD]
  • 우분투 14.04.2 LTS [UPSTART]
  • Fedora 릴리스 23 (온라인 셸) [SYSTEMD]
  • 데비안 GNU / 리눅스 7 (온라인 셸) [SYSTEMD]

동일한 솔루션에 대한보다 단순한 접근 방식 (그러나 첫 번째 일치시 중지)

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

좋은 첫 번째 대답. 유닉스에 오신 것을 환영합니다!
Olivier Dulac

방금 OpenRC가 설치된 젠투 기본 도커 이미지에서 이것을 시도했으며 SYSVINIT를 반환했습니다. wiki.gentoo.org/wiki/Comparison_of_init_systems 에 따르면 Gentoo의 기본값은 OpenRC이지만 OpenRC는 sysvinit를 사용하는 것으로 보입니다. 그런 다음 OpenRC 명령을 시도하면 "openrc가 부팅되지 않은 시스템에서 OpenRC 서비스를 실행하려고합니다."라는 메시지가 나타납니다. sysvinit을 사용하여 sysvinit와 OpenRC를 구별하는 방법이 있습니까?
tudor

9

때로는 다음과 같이 사용하기가 쉽습니다 ls .

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

/sbin/init기호 링크가 아닌 경우 다른 답변에서 다음 제안을 확인해야합니다.


3
  1. 이것이 배포판 전용 패키지입니다. init 시스템을 감지하는 것보다 소프트웨어를 올바르게 설치하는 것이 훨씬 더 많습니다. 많은 배포판에서 SysVinit를 사용하지만 모두 동일한 방식으로 초기화 스크립트를 작성하는 것은 아닙니다. 이 문제를 해결하는 올바른 방법은 모든 다른 변형을 포함시킨 다음 rpm 배포판의 배포 판별 종속성 이름이있는 사양 파일, apt 기반 시스템의 deb 파일 등을 사용하여 묶는 것입니다. 거의 모든 배포판에는 일종의 패키지 사양이 있습니다. 의존성, 스크립트, 초기화 스크립트 등을 포함하는 글을 쓸 수 있습니다. 여기서 바퀴를 다시 발명하지 마십시오.

  2. 아니요. 어느 것이 다시 우리를 1로 데려옵니다. bash가 필요하다면 그것은 의존적이어야합니다. 이 검사를 구성 스크립트의 일부로 지정할 수 있지만 패키지 설명에도 포함되어 있어야합니다.

편집 :--with upstart 또는 구성 스크립트에서 플래그를 사용하십시오 (예 : 또는) --without sysvinit. 적절한 기본값을 선택하면 다른 배포판 용 소프트웨어를 패키지로 제공하는 스크립트가 다른 옵션으로이를 실행하도록 선택할 수 있습니다.


흠, 그래서 '모든 것을 지배하는 하나의 스크립트'솔루션을 가질 수없는 것처럼 보입니다. 크로스 플랫폼을 처리하기 위해 autoconf 또는 이와 유사한 것을 사용하는 많은 프로그램을 보았지만 내 응용 프로그램에 적합한 도구 인 것 같지는 않습니다. 각 플랫폼의 버전을 유지하는 것이 실제로 유일한 유일한 솔루션입니까?
beatgammit

그들 모두를 지배하는 하나의 설치 스크립트는 BadIdea입니다. 작동하는 것보다 더 많은 장소에서 장애가 발생합니다. Autoconf는 가능한 한 좋습니다. 소프트웨어의 끝을 가능한 한 일반적으로 유지하고 패키지에 대체 init 스크립트를 포함시키기 위해 열심히 노력하십시오. 몇 가지 주요 배포판에 대한 설치 패키지 사양. 소프트웨어가 좋은 경우 다른 사람이 다른 시스템 용으로 패키지화하도록 도와 줄 수 있습니다.
Caleb

@ tjameson : 방금 내가 가장 중요한 것을 잊었다는 것을 깨달았습니다. 이러한 종류의 작업은 일반적으로 configure 스크립트로 전달 된 스위치로 수행됩니다. 각 배포판의 빌드 / 패키지 루틴은 서로 다른 스위치를 호출 할 수 있으며, 구성 / 만들기에는 통과 된 스위치 만 알아야하며 가능한 모든 소프트웨어 구성을 감지하지는 않습니다.
Caleb

@ Caleb- 그래, 나는 이미 그 논리를 가지고 있지만 잘 잡는다. 나는 init 시스템이 정상적인 기본값보다 지능적인 추측을 사용하도록 스니핑하는 방법을 원했습니다.
beatgammit

2

젠투에서는 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]

이 경우 initinit 시스템은 OpenRC입니다. 이 경우 systemdinit 시스템은 systemd입니다.

로 젠투를 감지 할 수 있습니다 [ -f /etc/gentoo-release ].

젠투의 또 다른 방법은를 사용 profile-config show하는 것인데, 이것은 사용중인 기본 프로파일을 보여줍니다. / systemd로 끝나는 두 개를 제외한 모든 프로필은 OpenRC init를 사용합니다. 이는 기본값을 나타내는 것일 뿐이며 사용자가 해당 기본값을 재정의하는 단계를 수행했으며 실제로 사용중인 초기화 관리자를 나타내지 않을 수도 있습니다.


바보 같은 질문이지만 어떻게 pid 1을 확인합니까?
Faheem Mitha

사용 p(동일 옵션 -p--pidPID에 의해 선택). 위의 스 니펫은 실제로에 대한 출력입니다 ps u --pid 1.
José M. Benítez

2

데비안에서 / sbin / init는 기본 init에 대한 심볼릭 링크이므로

ls -l /sbin/init

찾고있는 정보를 제공합니다.

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

1
별로. Upstart가 설치된 Ubuntu 14.04에서는 심볼릭 링크가 아닙니다.
muru December

다른 초기화 시스템을 설치하고 다시 확인하십시오.
rmorelli74

그리고 init우분투 14.04에는 어떤 것을 설치할 수 있습니까?
muru December

... sysv 또는 systemd가 아닌 이유
rmorelli74

1
공감하고 싶지 않다. 데비안의 어떤 버전이 적용되는지 지정하고 싶다. (그리고 아마도 "데비안 기반"을 "데비안"으로 바꾸어 그것이 정확 해 지도록하십시오.)
muru December

2

PID 1을 사용하여 프로세스를 간단히 파악하면 다음과 같이 알 수 있습니다.

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

언급 된 모든 OSeS에 proc파일 시스템 이있는 것은 아닙니다 .
Toby Speight

2

또한 파일 설명자를 검사하면 도움이 될 수 있습니다. 그리고 실제로 init을 실행하는 것입니다 (Debian stretch는 현재 더 많은 init 시스템을 설치할 수 있습니다) :-)

$ 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

busybox는 check /proc/1/exe일반적으로 symlink를 사용하므로 busybox를 확인하는 것이 더 안전한 방법 일 것입니다 .

$ ls -l /proc/1/exe 
lrwxrwxrwx    1 root     root          0 Jan  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 "unknown init"

또한 systemd가있는 시스템에는 일반적으로 directory가 /run/systemd/system있습니다.
pevik

2

Debian (wheezy) / Ubuntu (14.10.)와 같은 다른 시스템에 대해서는 모르지만 일반 이전 file명령으로 이러한 문제를 테스트 합니다.

file /sbin/init

이것을주세요 :

/sbin/init: symbolic link to 'upstart'

systemd(예 : sid)를 가진 데비안 시스템 은 이것을 보여줍니다 :

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

어떤 시스템에서 테스트 했습니까? 데비안 / 우분투와 같은 것은 없으며 데비안에서는 작동하지 않습니다. 우분투에서 사용해 보셨습니까?
terdon

이 혼란을 드려 죄송합니다. Debian (wheezy) 또는 Ubuntu (14.10.)를 의미합니다. 데비안에서의 출력 : 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를 사용한다는 의미입니다. 우분투의 출력이 내 답변에 표시됩니다.
zzeroo

정확히, 따라서 귀하의 솔루션은 upstart 및 Ubuntu를 사용하는 경우에만 작동하는 것 같습니다.
terdon

@terdon : systemd를 실행하는 시스템 (RHEL, Fedora)에서 "systemd에 대한 심볼릭 링크"를 반환합니다. upstart를 실행하는 시스템 (Ubuntu)에서 "upstart에 대한 심볼릭 링크"를 반환합니다. SysV init를 실행하는 시스템 (RHEL, Ubuntu, Debian)에서는 "실행 가능"을 반환합니다. 그것은 포괄적 인 설문 조사가 아니며,이 방법이 100 % 완전하지는 않지만, "업 스타트 및 우분투 만"보다는 "최소한 주요 배포판을위한 작업"에 훨씬 더 가깝습니다!
psmears

1
@psmears는 일부 시스템 시스템에서도 작동한다면 실제로 더 좋습니다 (그러나이 답변에서는 언급되지 않았습니다). 방금 sysvinit을 실행하는 데비안과 세 개의 Ubuntus (10.04,12.04 및 14.04, 모두 시작)를 테스트하고 file /sbin/init모든 시스템에서 "실행 가능"을 반환했습니다. 또한 CentOS 5.8, SLES 10, Ubuntu 8.04에서도 기본적으로 동일한 기능을 제공합니다. 따라서 내가 알 수있는 한 upstart 및 Ubuntu에서는 작동하지 않습니다.
terdon

2

나도 같은 문제가 있었고 일부 RedHat / CentOS / Debian / Ubuntu / Mint 머신에서 많은 테스트를 수행했습니다. 이것은 내가 끝내서 좋은 결과를 얻었습니다.

  1. PID 1로 실행 파일 이름을 찾으십시오.

    ps -p 1

    시스템 또는 시동 상태이면 문제가 해결 된 것입니다. "init"인 경우 심볼릭 링크이거나 이름이 아닌 다른 이름 일 수 있습니다. 어서

  2. 실행 파일의 실제 경로를 찾으십시오 (루트로만 작동).

    ls -l `which init`

    initUpstart 또는 시스템에 대한 심볼릭 링크 인 경우 문제가 해결되었습니다. 그렇지 않으면 SysV init이 거의 확실합니다. 그러나 이름이 잘못 지정된 실행 파일 일 수 있습니다. 어서

  3. 실행 파일을 제공하는 패키지를 찾으십시오. 불행히도 이것은 배포판에 따라 다릅니다.

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

그런 다음 스크립트를 작성하려면 (가장 재미있는 부분, IMHO), 이들은 내 단일 라이너입니다 (루트로 실행).

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
지정된 모든 운영 체제에 dpkg 또는 rpm이있는 것은 아닙니다 (이 문제는 귀하의 답변 인 BTW에만 국한되지는 않습니다).
Toby Speight

@ toby-speight 그렇습니다. 참고로 제한 사항을 명확히하기 위해 대답했습니다.
에머슨 프라도

3 단계 init --version에서 정보를 얻기 위해 실행할 수 있습니다 .
jarno

1

이것은 일부 init 시스템에서 정말 쉽습니다. systemd의 경우 :

test -d /run/systemd/system

시작을 위해 :

initctl --version | grep -q upstart

그 밖의 다른 것이라면, 배포판 (OS X에서 시작, 데비안에서 sysvinit, 젠투에서 OpenRC)을 기반으로 가정 할 수 있습니다.


"분포를 기반으로한다"는 데비안에서는 작동하지 않습니다. 적어도 세 가지 다른 init가 지원됩니다.
Toby Speight

1

감지를 수행하는 bash 스크립트는 다음과 같습니다. 현재 시작 및 시스템 검사 만 수행하지만 확장하기 쉬워야합니다. 나는 이것을 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
나는 /proc이것을 리눅스 (적절하게 구성된 경우)와 하나 또는 두 개의 다른 것과 의 유대 사용 이 보편적이라고는 생각하지 않습니다.
Toby Speight

1

systemd와 initd를 테스트 할 때 호환성 문제가 많이 있습니다. 이것은 실제로 OpenSuSE 42.1에서 작동합니다.ps --pid 1 | grep -q systemd && echo 'systemd' || echo 'init'


1

의 경우 systemd:

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

이 답변은 수많은 기존 답변과 비교하여 새로운 정보 나 다른 정보를 제공하지 않기 때문에
jayhendren

@ jayhendren 다른 곳에서는이 코드를 볼 수 없습니다. 그것은 그 자체로 완전하지, 그리고 아마도 더 나은 응답에 대한 주석으로 서 것 unix.stackexchange.com/a/164092/100397 TVE에 의해
roaima

아 맞다 @roaima. 다른 것과 정확히 동일하지 않습니다. 나는 :)하지 않은 너무 특정 문자열에 대한 페이지 검색
jayhendren

1
이것은 가장 정답 인 것 같습니다 :)
Jack O'Connor

1

내 솔루션 : 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

현재 Init 및 SystemD 시스템에만 액세스 할 수 있으므로 Upstart 또는 macOS (OS X)가 어떻게 감지되는지 알 수 없지만 계속 검색하겠습니다.


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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.