이는 아마도 운영 체제 감지와 더 관련이 있을 수 있지만 특히 현재 시스템에서 사용 중인 init 시스템이 필요합니다.
Fedora 15 및 Ubuntu는 이제 systemd를 사용하고 Ubuntu는 Upstart(15.04까지의 기본값)를 사용하며 다른 버전은 System V 변형을 사용합니다.
저는 크로스 플랫폼 데몬으로 애플리케이션을 작성하고 있습니다. 초기화 스크립트는 구성 중에 전달된 매개변수를 기반으로 동적으로 생성됩니다.
내가 원하는 것은 그들이 사용하고 있는 특정 초기화 시스템에 대한 스크립트를 생성하는 것뿐입니다. 이런 방식으로 설치 스크립트는 인수 없이 루트로 합리적으로 실행될 수 있으며 데몬은 자동으로 "설치"될 수 있습니다.
이것이 내가 생각해낸 것입니다:
- /bin에서 systemd, upstart 등을 검색하세요.
- /proc/1/comm을 systemd, upstart 등과 비교하십시오.
- 사용자에게 물어보세요
이 작업을 수행하는 가장 좋은 크로스/플랫폼 방법은 무엇입니까?
어느 정도 관련이 있고,대부분의 *nix를 지원하기 위해 bash를 사용할 수 있습니까? 아니면 배포/OS에 종속됩니까?
대상 플랫폼:
- 애플 시스템
- Linux(모든 배포판)
- BSD(모든 버전)
- Solaris, Minix 및 기타 *nix
답변1
나는 이 문제에 직접 직면했고 몇 가지 테스트를 하기로 결정했습니다. 유통마다 별도의 포장이 있어야 한다는 답변에는 전적으로 동의합니다만, 때로는 현실적인 문제(특히 인력)가 있을 수 있습니다.
그래서 "자동 감지"를 원하는 사람들을 위해 이것이 내가 찾은 것입니다.제한된 배포 세트에 대해(자세한 내용은 아래에서):
다음을 통해 신생 기업을 발견할 수 있습니다.
[[ `/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 인스턴스에서(us-east AMI ID를 포함했습니다):
- ArchLinux: systemd 사용(이후2012.10.06)
- CentOS6.4 ami-52009e3b: upstart 사용
- CentOS7 ami-96a818fe: systemd 사용
- 데비안 6 ami-80e915e9: sysv-init 사용
- 데비안 7.5 ami-2c886c44: sysv-init 사용
- Debian 7.6 GCE 컨테이너 가상 머신: 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가 있다면 수정하도록 노력하겠습니다...
답변2
두 번째 질문에 대한 대답은 다음과 같습니다.아니요너는 좀 봐야 해휴대용 쉘 프로그래밍 리소스.
첫 번째 부분에 관해서는 - 우선 조심해야 합니다. 내가 말할 것여러 테스트를 수행하여 보장합니다.- 실제로 사람이 있기 때문에물론예를 들어 systemd가 설치되었다고 해서 실제로 기본 init
. 또한, 다양한 init 프로그램의 일부 설치가 자동으로 심볼릭 링크 하드링크를 생성하거나 심지어 기본 프로그램의 이름이 변경된 버전을 생성 /proc/1/comm
할 수 있으므로 보는 것이 오해의 소지가 있을 수 있습니다./sbin/init
아마도 가장 유용한 것은 init 스크립트 유형을 살펴보는 것일 것입니다. 이는 실행 중인 항목에 관계없이 실제로 생성하려는 것이기 때문입니다.
그건 그렇고, 당신도 확인할 수 있습니다오픈RC그 목적은 Linux 및 BSD 시스템과 호환되는 init 스크립트 구조를 제공하는 것입니다.
답변3
수동
&의 다양한 버전을 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의 프로세스 이름은 어떤 초기화 시스템이 사용되고 있는지 이해하는 데 도움이 될 수도 있습니다. 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/init
sysvinit 시스템에 있습니다 .
시스템 베넷
$ type init
init is /sbin/init
이:
$ sudo init --version
init: invalid option -- -
Usage: init 0123456SsQqAaBbCcUu
결론적으로
따라서 이를 수행하는 한 가지 방법은 없는 것 같지만 어떤 초기화 시스템을 사용하고 있는지 상당히 높은 신뢰도를 가지고 정확히 찾아내는 일련의 검사를 개발할 수 있습니다.
답변4
때로는 다음을 사용하는 것만큼 간단합니다 ls
.
$ ls -l /sbin/init
lrwxrwxrwx 1 root root 20 juin 25 12:04 /sbin/init -> /lib/systemd/systemd
/sbin/init
심볼릭 링크가 아닌 경우 다른 답변에서 다음 제안을 추가로 확인해야 할 것 같습니다 .