Kabuğu kullanarak init sistemini tespit etme


90

Bunun işletim sistemlerini tespit etmekle daha fazla ilgisi olabilir, ancak özellikle şu anda sistemde kullanımda olan init sistemine ihtiyacım var.

Fedora 15 ve Ubuntu şimdi systemd kullanıyor, Ubuntu Upstart'ı kullanıyordu (uzun süre 15.04'e kadar uzun süre varsayılan), diğerleri ise System V varyasyonlarını kullanıyordu.

Platformlar arası bir arka plan programı olarak yazdığım bir uygulamam var. İnit betiği, configure ile geçirilebilecek parametrelere dayanarak dinamik olarak oluşturuluyor.

Yapmak istediğim sadece kullandıkları belirli init sistemi için senaryoyu oluşturmak. Bu şekilde kurulum betiği root olarak parametreler olmadan makul şekilde çalıştırılabilir ve arka plan programı otomatik olarak "kurulabilir".

Bu benim geldiğim şey:

  • Systemd, upstart, vb / bin dizininde ara
  • / Proc / 1 / comm komutunu sistemd, başlangıç, vb. İle karşılaştırın.
  • Kullanıcıya sor

Bunu yapmanın en iyi çapraz / platform yolu ne olurdu?

İlişkili, bash’ın * nix’in çoğunluğuna bağlı olmasına bağlı mıyım, dağıtım / işletim sistemine bağlı mı?

Hedeflenen platformlar:

  • Mac os işletim sistemi
  • Linux (tüm dağıtımlar)
  • BSD (tüm sürümler)
  • Solaris, Minix ve diğer * nix

1
Sadece iki kuruş eklemek için, bash FreeBSD'de varsayılan olarak kurulu değil.
Chinmay Kanchi

@tjameson, daha doğrudan bir yol buldunuz mu? Aynı şeyi arıyorum ama buradaki cevaplar doğrudan yönlendirme değil, sadece yönlerdir. Özellikle 1) aranacak komut dosyası konumlarını ve 2) kurulu olan birden fazla kişinin olması durumunda, init sisteminin tespit edilmesi (bash doğrudan cevaplandı).
n611x007

3
@ naxa - Kısa cevap, hayır. Uzun cevap, oldukça uzaklaşabilirsiniz ps -p 1 -o command(akıntıya giden yolu basar init). Arch Linux ve Fedora'da (IIRC), bu ikiliye bir bağlantı systemd(muhtemelen tüm systemdsistemlerde aynıdır ). Açık upstart, init --helpkullanım bilgilerini yazdıracak ve kutumda upstartkime e-posta gönderileceği belirtiliyor. FreeBSD'de (sysV) bu bir hata verecektir. Diğer sistemlerde de benzer ipuçları olabilir, ancak bu soruyu sorduğundan beri, onları tüm platformlar için yaratmaya ve her biri için ayrı paketler oluşturmaya karar verdim.
48'de

teşekkürler harika bilgi! Bundan sudo lsof -a -p 1 -d txtdaha da kesin sonuçlar verebileceğini öğrendim . psİsteğe bağlı bir ad yazdırabilir, oysaki lsofsizinle gerçek çalıştırılabilir yolu elde edebilirsiniz. (Bkz. Sorumu unix.stackexchange.com/questions/102453/… )
n611x007 24:13

1
Bağlantılı sorudaki cevapların veya yorumların hiçbiri bash ile ilgili değildir. Çözümler sizin için de geçerli olmalıdır.
Marco,

Yanıtlar:


30

İkinci soru için, cevap hayır ve bir göz olmalıdır taşınabilir kabuk programlama için Kaynaklar .

İlk bölüme gelince - her şeyden önce, kesinlikle dikkatli olmalısınız. Diyorum ki emin olmak için çeşitli testler - Biri gerçeği nedeniyle gelmiş gelmez (. Ex) systemd yüklü, aslında varsayılan olarak kullanılır anlamına gelmez init. Ayrıca bakmak, /proc/1/commyanıltıcı olabilir, çünkü çeşitli init programlarının bazı kurulumları otomatik olarak /sbin/initbir link link bağlantısı veya ana programlarının yeniden adlandırılmış versiyonunu yapabilir.

Belki de en faydalı olan şey init betik tipine bakmak olabilir - çünkü bunlar neyi çalıştırırsa yaratın ne olacaksa bunlar.

Bir yandan not olarak, hem Linux hem de BSD sistemleriyle uyumlu bir init betiği yapısı sağlamayı amaçlayan OpenRC'ye bakabilirsiniz .


2
Ne demek "init betikleri türüne bak" derken? Genellikle farklı init sistemleri komut dosyalarını / dosyalarını bir yere /etc/initkoyar, systemd bunları koyar gibi /etc/systemd. Senaryomu bunlara çarptırdıysam, biraz zaman alabilir. Oh, ve portatif kabuk programlama için bağlantı BTW için teşekkürler.
beatgammit

1
Bazı init uygulamalarının, farklı init betiklerinin tiplerinden ve konumlarından ( /etc/rc.d/ya da gibi /etc/init.d/) faydalanmak için ayarlanabileceğini söylemek istedim . Ve verilen sistemde kullanılan yapıdan yararlanmak için kurulum sırasında programınızı uygun şekilde ayarlamalısınız .
rozcietrzewiacz

2
Yani, init sistemini programlı olarak tespit etmenin güvenilir bir yolu olmadığını mı söylüyorsunuz? Kullanıcının parametreleri geçmesi kesinlikle daha güvenlidir, ancak kullanıcı hiçbir şeyi geçmezse, tahmin etmenin en iyi yolu ne olurdu?
beatgammit

Programınız için en iyi yolun ne olacağı hakkında hiçbir fikrim yok - bunlar programın hangi sistemlerin çalışacağına bağlı. Çok fazla dağıtım kullanmadım, ancak size yardımcı olmak için gözlemlerimi paylaşmaya çalışıyordum. Denemek üzere olduğunuz zorlu bir komut dosyası parçası ve size alan hakkında bir fikir vermeye çalıştım - son cevaba kendiniz gelmeli veya daha fazla ipucu beklemelisiniz.
rozcietrzewiacz

Harika, yardımın için teşekkürler. Beni kesinlikle doğru yöne çevirdin.
beatgammit

58

Bu soruna kendim girdim ve bazı testler yapmaya karar verdim. Her dağıtım için ayrı ayrı paketlenmesi gereken cevaba tamamen katılıyorum, ancak bazen bunu engelleyen pratik meseleler var (en az insan gücü değil).

Bu nedenle, "otomatik algılamayı" isteyenler için , sınırlı bir dizi dağıtımda bulduğum şey (aşağıda daha fazlası):

  • Sen start-up söyleyebilir:

    [[ `/sbin/init --version` =~ upstart ]] && echo yes || echo no
  • Systemd'ye şunu söyleyebilirsin:

    [[ `systemctl` =~ -\.mount ]] && echo yes || echo no
  • Sys-v init’i şuradan söyleyebilirsiniz:

    [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]] && echo yes

İşte aşağıdaki komut satırı ile deneylerim:

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 örneklerinde (ABD-doğu AMI kimliğini dahil ediyorum):

  • ArchLinux: systemd kullanıyor ( 2012.10.06'dan beri )
  • CentOS6.4 ami-52009e3b: başlangıç ​​noktasını kullanma
  • CentOS7 ami-96a818fe: sistemi kullanma
  • Debian 6 ami-80e915e9: sysv-init kullanarak
  • Debian 7.5 ami-2c886c44: sysv-init kullanarak
  • Debian 7.6 GCE container-vm: sysv-init kullanarak
  • RHEL 6.5 ami-8d756fe4: başlangıç ​​özelliğini kullanarak
  • SLES 11 ami-e8084981: sysv-init kullanımı
  • Ubuntu 10.04 ami-6b350a02: başlatma özelliğini kullanma
  • Ubuntu 12.04 ami-b08b6cd8: başlatma işlevini kullanma
  • Ubuntu 14.04 ami-a427efcc: başlangıç ​​noktasını kullanma
  • Ubuntu 14.10 ve daha genç: systemd kullanarak
  • AWS linux 2014.3.2 ami-7c807d14: başlatma özelliğini kullanma
  • Fedora 19 ami-f525389c: sistemi kullanma
  • Fedora 20 ami-21362b48: sistemi kullanma

Sadece açık olmak gerekirse: Bunun kusursuz olduğunu iddia etmiyorum! , neredeyse kesinlikle değil. Ayrıca kolaylık olması için her yerde bulunmayan bash regexp maçları kullandığımı unutmayın. Yukarıdakiler şu anda benim için yeterince iyi. Ancak, başarısız olduğu bir dağıtım bulursanız, lütfen bana bildirin ve sorunu yeniden üreten bir EC2 AMI varsa düzeltmeye çalışacağım ...


5
Sistem belgelerine göre ( sd_booted (3) ), sistem kodunu kontrol etmenin doğru yolu dizinin /run/systemd/systemvar olup olmadığını kontrol etmektir .
Robie Basak,

1
Bu algılamaya ekleyeceğim launchd, macOS'taki init sistemi: [[ $(ps 1) =~ 'launchd' ]] && echo yes || echo noMacBookPro'da test edilmiş, macOS Sierra Sürüm 10.12
Tony

Ayrıca busybox if [ -h /sbin/init -a $(readlink /sbin/init | grep busybox | wc -l) -gt 0 ]; then echo yes; else echo no; fi
eklerdim

18

Süreçleri kullanarak

Bir çift gelen çıkış baktığımızda psçeşitli versiyonlarını tespit edebilen komutlar systemd& upstartşöyle hazırlanmış olabilir:

sonradan görme

$ 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

systemd

$ 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 olan sürecin ismine dikkat etmek, potansiyel olarak init sisteminin kullanılmakta olduğuna da ışık tutabilir. Fedora 19'da ( systemdörneğin:

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

Fark etmeyin init. Upstart ile Ubuntu'da hala var /sbin/init.

$ ps -efa|grep init
root         1     0  0 Jan02 ?        00:00:03 /sbin/init

NOT: Fakat bunu biraz dikkatli kullanın. Belirli bir init sistemi belirtilen bir dağıtımı kullanılıyor diyor taş koymak hiçbir şey yok etmiştir olması systemdPID 1. olarak.

genel

$ (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 sürecinin çocukları) olan işlemlere bakın. (Bazıları) alt süreç adları, kullanılan init sistemine işaret edebilir.

Dosya sistemi

initYürütülebilir dosyayı sorgularsanız, ondan da bilgi alabilirsiniz. Basitçe --versionçıktıyı ayrıştırma . Örneğin:

sonradan görme

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

systemd

$ type init
init is /usr/sbin/init

NOT: Aslında initstandart konumda değil bir ipucu biraz / anlatmak. Her zaman /sbin/initsysvinit sistemlerinde bulunur.

sysvinit

$ type init
init is /sbin/init

Ayrıca bu:

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

Sonuçlar

Dolayısıyla, bunu yapmanın bir yolu görünmüyor, ancak hangi init sistemini oldukça yüksek bir güvenle kullandığınızı belirten bir kontrol paketi oluşturabilirsiniz.


Peki ya:pgrep systemd >/dev/null && echo init system: systemd
Marco,

Teşekkürler, bu tam olarak aradığım şeydi: init sistemini belirlemeye çalışmak için atılacak bazı adımlar.
user369450

1
PID # 1, mutlaka /usr/lib/systemd/systemdsistemd kullanılıyorsa, yanlış bir varsayımda bulunmaz . Sistemimde, örneğin PID # 1 /sbin/init(systemd kullanıyorum). Dağılıma bağımlıdır.
Marco,

15.04 kubuntu kurulumumda hem systemd hem de sysvinit var. Bilmiyorum neden ya bunun ne anlama sadece söyleyerek .. pgrep systemd >/dev/null && echo init system: systemd -> init system: systemdvetype init -> init is /sbin/init
dotnetCarpenter

12

O kadar verimli değil ama iş gibi görünüyor.

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

Birden fazla karakter dizisi eşleşirse "tahmin edilemez" e çevrilebilecek daha fazla satır yazdıracaktır. Grep'te kullanılan dizeler hafifçe değiştirilebilir, ancak aşağıdaki işletim sistemlerinde test edildiğinde her zaman bir satır elde ettim.

  • RHEL 6.4 [BAŞLANGIÇ]
  • RHEL ES 4 (Nahant Güncelleme 7) [SYSVINIT]
  • Ubuntu 16.04.1 LTS [SİSTEM]
  • Ubuntu 14.04.2 LTS [UPSTART]
  • Fedora sürüm 23 (çevrimiçi kabuk) [SYSTEMD]
  • Debian GNU / Linux 7 (çevrimiçi kabuk) [SYSTEMD]

Aynı çözüme daha basit bir yaklaşım (ancak ilk maçta durur)

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

güzel ilk cevap. unix.se'ye hoş geldiniz!
Olivier Dulac

Bunu OpenRC yüklü Gentoo varsayılan liman işçisi görüntüsünde denedim ve SYSVINIT döndürdü. Wiki.gentoo.org/wiki/Comparison_of_init_systems'a göre Gentoo için varsayılan OpenRC'dir, ancak OpenRC'nin sysvinit kullandığı anlaşılmaktadır. Daha sonra OpenRC komutlarını denediğimde "OpenRC hizmetini açılış yapmayan bir sistemde OpenRC servisi çalıştırmaya çalışıyorsunuz" alıyorum. Sysvinit kullanarak OpenSC ile sysvinit arasında ayrım yapmanın bir yolu var mı?
tudor

9

Bazen kullanmak kadar kolaydır ls :

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

Sanırım /sbin/initsembolik bir bağlantı değilse , diğer cevaplardaki önerileri izleyerek daha sonra kontrol etmeniz gerekecektir.


3
  1. Dağıtıma özel paketler bunun içindir. Doğru bir şekilde yazılımı kurmak sadece init sistemini tespit etmekten çok daha fazlasıdır. Pek çok dağıtım SysVinit kullanıyor, ancak hepsi init komut dosyalarını aynı şekilde yazmıyor. Bunu çözmenin doğru yolu, tüm farklı varyantları dahil etmek ve sonra bunu rpm dağıtımları, dağıtım tabanlı sistemler için deb dosyaları, apt tabanlı sistemler için deb dosyaları vb. Bağımlılıklar, senaryolar, init komut dosyaları, vb. içeren yazabilir. Tekerleği burada yeniden icat etmeyin.

  2. Hayır. Bizi tekrar 1'e geri getiriyor. Eğer bash'a ihtiyacınız varsa, bir bağımlılık olmalıdır. Bu kontrolü configure betiğinizin bir parçası olarak belirleyebilirsiniz, ancak paket açıklamalarında da olmalıdır.

Düzenleme: configure betiğinizde --with upstartveya gibi bayraklar kullanın --without sysvinit. Akıllıca bir varsayılan seçin; ardından yazılımınızı diğer dağıtımlar için paketleyen komut dosyaları, bunu diğer seçeneklerle çalıştırmayı seçebilir.


Hmph, bu yüzden 'hepsini yöneten tek bir senaryo' çözümüne sahip olamayacağımı düşünüyorum. Platformlar arası işlemleri yapmak için autoconf kullanan veya benzer programlar kullanan pek çok program gördüm, ancak uygulamam için doğru araç gibi görünmüyor. Her platform için sürümleri korumak gerçekten tek güvenilir çözüm mü?
beatgammit

Hepsine hükmedecek bir komut dosyası, bir BadIdea'dır. Çalıştığından daha fazla yerde başarısızlıkla sonuçlanır. Autoconf gittiği kadar iyidir. Yazılımınızın sonunu mümkün olduğunca genel tutmak için çok çalışın ve paketinize alternatif init betikleri ekleyin. Birkaç önemli dağıtım için kurulum paketi spesifikasyonları. Yazılımınız iyiyse, başkalarının da diğer sistemler için paketlenmesinde size yardımcı olmalarını sağlayabilirsiniz.
Caleb

@tjameson: En önemli kısmı unuttuğumu fark ettim. Bu tür şeyler genellikle configure betiğine geçirilen anahtarlarla yapılır. Her dağıtımın yapı / paket yordamları farklı anahtarları çağırabilir ve config / make'iniz hangi anahtarın geçtiğini bilmek zorundadır, tüm olası yazılım yapılandırmalarını algılamamaktadır.
Caleb

@ Caleb- Evet, zaten orada o mantık var, ama iyi yakalamak. Akıllı bir tahminde bulunmadan akıllı bir tahmin kullanmak için init sistemini koklamanın bir yolunu umuyordum.
beatgammit

2

Gentoo’da, 1. paragrafa bir göz atın:

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]

Öyleyse init, init sistemi öyledir OpenRC. Öyleyse systemd, init sistemi öyledir systemd.

Gentoo ile tespit edebilirsiniz [ -f /etc/gentoo-release ].

Gentoo'daki bir diğer yöntem ise profile-config showhangi varsayılan profilin kullanıldığını gösterecek olan kullanmaktır. İkisi de / systemd biten dışındaki tüm profiller OpenRC init kullanın. Unutmayın, bunlar yalnızca bir temsili temsil eder ve kullanıcının bu varsayılanı geçersiz kılmak için adımlar atması ve gerçekte kullanımdaki init yönetiminin bir göstergesi olmayabilir.


Aptalca bir soru, ama pid 1'i nasıl kontrol edebilirim?
Faheem Mitha

PID ile seçmek piçin (aynı -pve ile aynı --pid) seçeneğini kullanın . Yukarıdaki kod parçası aslında için çıktı ps u --pid 1.
José M. Benítez

2

Debian / sbin / init, varsayılan initinize bir bağlantıdır.

ls -l /sbin/init

Size aradığınız bilgileri verecektir.

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

1
Öyle değil. Upstart ile Ubuntu 14.04'te bu bir bağlantı değil.
muru

Başka bir init sistemi kurun ve tekrar kontrol edin.
rmorelli74

Ve başka hangi initUbuntu 14.04'e yükleyebilirim?
muru

... neden sysv veya systemd değil?
rmorelli74

1
Oy vermek istemiyorum, yalnızca hangi Debian sürümüne uygulanabilir olduğunu belirtmenizi istiyorum. (Ve belki de "Debian-tabanlı"
kelimesini

2

PID 1 ile işlemin kolayca anlaşılması size şunu söyleyecektir:

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

Bahsedilen tüm OSeS'lerin bir procdosya sistemi yok ...
Toby Speight

2

Ayrıca dosya tanımlayıcılarını incelemek de yardımcı olabilir. Ve aslında çalışan init'ten (Debian stretch şu anda daha fazla init sisteminin kurulmasına izin veriyor) :-)

$ 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 kontrol etmek için muhtemelen daha güvenli bir yol olacaktır check /proc/1/exebusybox genellikle sembolik kullandığından,:

$ ls -l /proc/1/exe 
lrwxrwxrwx    1 root     root          0 Jan  1 00:00 /proc/1/exe -> /bin/busybox

Yani kontrol olabilir:

{ 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"

Ayrıca systemd bulunan sistemlerde genellikle dizin bulunur /run/systemd/system.
pevik

2

Debian (wheezy) / veya Ubuntu (14.10.) 'Dan sonra diğer sistemler hakkında bir şey bilmiyorum ama bu tür sorunları düz eski filekomutla test ediyorum .

file /sbin/init

bunu ver:

/sbin/init: symbolic link to 'upstart'

Debian sistemleri systemd(örneğin sid) şunu gösterir:

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

Hangi sistemde test ettin? Debian / Ubuntu diye bir şey yoktur ve bu Debian üzerinde çalışmaz. Ubuntu'da denedin mi?
terdon

Bu karışıklık için özür dilerim, yani Debian (wheezy) / veya Ubuntu (14.10.). Debian çıktısı: 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 burada SYSV kullandığımız anlamına gelir. Ubuntu için çıktı cevabımda gösteriliyor.
zzeroo

Kesinlikle, bu yüzden çözümünüz yalnızca biri başlangıç ​​ve Ubuntu kullanıyorsa işe yarar gibi görünüyor.
terdon

@terdon: systemd çalıştıran sistemlerde (RHEL, Fedora), "sembolik bağlantıyı ... systemd" e döndürür; starttart çalışan sistemlerde (Ubuntu) "start-up'a sembolik link" döndürür; SysV init çalıştıran sistemlerde (RHEL, Ubuntu, Debian) "çalıştırılabilir" döndürür. Her ne kadar kapsamlı bir anket olsa ve bu yöntem% 100 kusursuz olmasa da, “sadece başlangıç ​​ve Ubuntu” yerine “en azından büyük dağıtımlar için çalışır” a çok daha yakın!
psmears

1
Ayrıca bazı sistem sistemleri için de çalışıyorsa @ psmears, bu gerçekten daha iyi (ancak bu cevapta bahsedilmedi). Az önce Debian çalışan bir sysvinit ve üç Ubuntus (10.04,12.04 ve 14.04, hepsi başlangıçta çalışıyor) üzerinde test ettim ve file /sbin/inittüm sistemlerde "çalıştırılabilir" ifadesini döndürdüm. Aynı zamanda, bir CentOS 5.8, bir SLES 10, bir Ubuntu 8.04, temelde elimde tutabileceğim her sistemde aynı şeyi veriyor. Yani, söyleyebildiğim kadarıyla başlangıç ​​ve Ubuntu için bile işe yaramaz.
terdon

2

Aynı sorunu yaşadım ve bazı RedHat / CentOS / Debian / Ubuntu / Nane makinelerinde birçok test yaptım. İyi sonuçlarla sonuçlandığım şey buydu.

  1. PID 1 ile çalıştırılabilir dosyanın adını bulun:

    ps -p 1

    Sistemdeyse veya Başlangıcı ise, problem çözüldü. Eğer "init" ise, bir sembolik bağlantı veya açık bir ad dışında bir şey olabilir. Devam et.

  2. Yürütülebilir dosya için gerçek yolu bulun (sadece root olarak çalışın):

    ls -l `which init`

    Eğer initUpstart veya systemd için bir link ise, problem çözüldü. Aksi takdirde, SysV init'iniz olduğu neredeyse kesindir. Ancak yanlış adlandırılmış bir çalıştırılabilir olabilir. Devam et.

  3. Yürütülebilir dosyayı sağlayan paketi bulun. Ne yazık ki, bu dağınık bağımlıdır:

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

Öyleyse, onu (en komik bölüm, IMHO) belirtmek isterseniz, bunlar benim tek gömleklerim (root olarak çalıştırın):

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
Belirtilen tüm işletim sistemlerinde dpkg veya rpm yoktur (bu sorun yalnızca sizin cevabınıza, BTW'ye özgü değildir).
Toby Speight

@ toby-speight Evet, elbette. Not Sadece sınırlamayı açıklığa kavuşturmak için cevabımda yazdım.
Emerson Prado

Adım 3'e gelince init --version, bilgi almak için koşabilirsiniz .
jarno

1

Bazı init sistemleri için bu gerçekten kolaydır. Systemd için:

test -d /run/systemd/system

başlangıç ​​için:

initctl --version | grep -q upstart

başka herhangi bir şey için, dağıtıma dayanarak varsayım yapabilirsiniz (OS X’de başlatılmış, Debian’da sysvinit, Gentoo’da OpenRC).


"dağıtıma dayalı varsaymak", en az üç farklı girişin desteklendiği Debian için işe yaramadı ...
Toby Speight

1

İşte algılama yapmak için bir bash betiği. Sadece şu anda başlangıç ​​ve sistem kontrolü yapar, ancak genişletilmesi kolay olmalıdır. Bunu DisplayLink driver kurulum komut dosyasına katkıda bulunduğum koddan aldım .

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
Sanırım bunun /procLinux'a (uygun şekilde yapılandırılmışsa) ve bir veya iki diğerine bağlanması - kesinlikle evrensel olmaktan uzak.
Toby Speight

1

İnitd'ye karşı systemd test edilirken birçok uyumluluk tehlikesi vardır. Bu aslında OpenSuSE 42.1'de çalışıyor:ps --pid 1 | grep -q systemd && echo 'systemd' || echo 'init'


1

İçin systemd:

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

Çünkü bu cevap mevcut sayısız cevapla karşılaştırıldığında yeni ya da farklı bilgi sağlamıyor.
jayhendren

@ jayhendren Bu snippet'i başka bir yerde göremiyorum. Kendi içinde tamamlanmadı ve büyük olasılıkla daha iyi bir yanıt olarak durmak daha iyi olurdu unix.stackexchange.com/a/164092/100397 , TvE
roaima

Oh haklısın @roaima. Diğerleriyle tam olarak aynı değil. Çok özel olmayan bir dize için sayfayı aradım :)
jayhendren

1
Bu, şu ana kadarki en doğru cevap gibi görünüyor :)
Jack O'Connor,

1

Benim çözümüm: ID 1 ile işlem halinde çalışan komutu kontrol edin.

case `cat /proc/1/comm` in
    init)    echo Init ;;
    systemd) echo SystemD ;;
    # add here other patterns
    *)       echo "unknown: '`cat /proc/1/comm`'" ;;
esac

Şu anda yalnızca Init ve SystemD makinelere erişebiliyorum, bu yüzden Nasıl Başlatma veya macOS'un (OS X) algılanacağını anlayamıyorum, ancak aramaya devam edeceğim.


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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.