
これはおそらくオペレーティングシステムの検出に関連しているかもしれませんが、特に現在システムで使用されている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を使用する
- Debian 6 ami-80e915e9: sysv-init の使用
- Debian 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
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
シンボリックリンクではない場合は、他の回答で次の提案をさらに確認する必要があるようです。