Systemd-tmpfiles çalıştıran bir systemd .service dosyası nasıl yazılır


16

systemd-tmpfiles --createBir systemd distro ile önyükleme işlemi sırasında çalıştırmak gerekir . Bu yüzden bu işi yapan bir systemd .service dosyası oluşturmam gerekiyor.

Bu soruda neye ve neye ihtiyacım olduğuna dair tüm detayları okuyabilirsiniz: systemd-tmpfiles nasıl çalışır?

Bu konuda bazı dokümanlar okudum ve aşağıdaki testi yazıyorum:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

Ama emin değilim, çünkü systemd-tmpfilesbasit bir program değil, bir sistemd parçası. Sistemimi kırmak istemiyorum.

Herhangi bir doğru .service dosyası hakkında ipucu?


Freedesktop.org/wiki/Software/systemd adresindeki systemd ile ilgili bolca belgelere bakın . Sistem varsayılanlarını kendi dosyalarınızla geçersiz kılabilirsiniz.
vonbrand

Yanıtlar:


30

[Bu doğrudan systemd-tmpfiles sorununu ele almaz, ancak bu özel durumda sadece yankı kullanarak daha iyi olduğunuzu zaten fark etmişsinizdir.]

İlk olarak, "multi-user.target" kullanmak istediğiniz şey olabilir veya olmayabilir. SysV tarzı init öğelerinden çalışma düzeyi kavramına aşina iseniz, çok kullanıcılı, GUI yerine bir konsola önyüklenen çok kullanıcılı bir sistem olan runlevel 3'ün sistemd eşdeğeri. X'e önyükleme yapan çalışma seviyesi 5'in eşdeğeri grafiksel hedeftir . Varsayılan, default.target adı verilen bir symlink tarafından belirlenir /etc/systemd/system(ve / veya /lib/systemd/system; içinde olanı /etcgeçersiz kılar /lib) , işaret ettiği yeri bulmak için ls kullanın:

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

Normal linux masaüstü bilgisayarlar için bu grafiksel olacaktır. Hedef. Varsayılan çalışma düzeyi / hedefinin ne olduğuna bakılmaksızın oluşturduğunuz önyükleme hizmetinin başlatılmasını istiyorsanız, bu aslında önemli değildir - bu durumda, default.target'ı kullanabiliriz ve bunun takma adının ne olduğu konusunda endişelenmeyiz. Ancak, çok kullanıcılı kullanıyorsanız ve varsayılanınız grafikse, hizmetiniz gerçekleşmez.

Servise bağlı olarak, bu konuyla ilgili olarak başlatmak istediğiniz daha uygun ve spesifik hedefler veya hizmetler olabilir. Diğer sorunuza dayanarak, default.target muhtemelen iyidir. Not olarak, bir "hedef" ve "hizmet" arasındaki fark, bir hizmetin [Service]gerçekte bir işlemi çalıştıran bir bölüm içermesidir; bir hedef, hizmetleri çeşitli "bağımlı" ve "gerektirir" direktifleri aracılığıyla bir arada gruplamanın bir yoludur; diğer hedefleri veya hizmetleri tetiklemenin ötesinde hiçbir şey yapmaz.

Bir hizmetin başladığı zaman, diğer hizmetlerin açıkça hangi hizmetlere bağlı olduğuna göre belirlenir. Önyükleme işleminde geç kalmasını istediğimiz basit, bağımsız bir olay söz konusu olduğunda, bu direktif kombinasyonunu kullanabiliriz:

[Unit]
After=default.target

[Install]
WantedBy=default.target

"Install" bölümü servis yüklendiğinde kullanılır; "WantedBy", bu hizmetin dahil edilmesini istediğimiz bir hedefi belirtir (yani, bu hedef işe yararsa çalışacaktır, ancak bu başkalarıyla ilişkili olarak ne zaman çalışacağını belirlemez ). Bu hizmetin daha erken değil daha geç çalışmasını istediğimizden, bir "Sonra" yantümcesi belirtiriz. Bu aslında WantedBy hedefi ile aynı olmak zorunda değildir (genellikle değildir) ve ne zaman umursamıyorsanız tamamen atlanabilir; Ben sadece diğer birçok şey belirtilen bir şey Before=default.target(ki biz de kullanılmış olabilir; hedef çalıştırılmadan önce bir hedefin istekleri değerlendirilir) zincirlenmiş bir şeyler ile ilgili olarak çalıştırılacak öbek üzerinde kullanıyorum .

Örnek olarak, "merhaba dünya" yı konsola yansıtacağım. Hizmetin kendisi [Service]bölümünde açıklanmıştır :

[Service]
Type=forking
ExecStart=/usr/local/bin/helloworld

Komutun tam bir yola ihtiyacı var. Sadece kullanmamamın nedeni /usr/bin/echo "hello world", çalışmayacak (çıktı / dev / null, sanırım) ve echo "hello world" > /dev/consoleirade yapan bir hizmet olsa da, deneyler bir ExecStart yönergesinde kabuk yönlendirme kullanmanın işe yaramayacağını gösteriyor . Yani / usr / local / bin / helloworld bu satırda bir kabuk betiğidir echo "hello world" > /dev/console.

Not Type=forkingbir kabuk için gerekli olan,.

Bizim komple minimal hizmet dosya sadece bu üç bölüm olduğunu ( [Unit], [Service]ve [Install]). Yüklemek için, dosyayı veya bir sembol bağlantısını / etc / systemd / system veya / usr / lib / systemd / system dizinine yerleştirin ve:

systemctl --system enable helloworld

Yazdırmalıdır ln -s .... Bu, hizmeti çalıştırmaz, yalnızca yukarıda açıklandığı gibi önyüklemede çalışacak şekilde yapılandırır.

Kısacası bu kadar. man systemd.unitve man systemd.servicedaha fazla ayrıntıya sahip.


1
Teşekkür ederim, çok yararlı cevap ve problem çözüldü. Sadece bir nota benim dağıtıma (Chakra Linux) default.targetdeğil /etc/systemd/system, ancak yalnızca öyle/usr/lib/systemd/system
Eang

Komutlardan çıktı kaydedilir (başka nereye gidebilir)?
vonbrand

/ Usr / lib / systemd / ... dosyaları yedek (varsayılan), sizinkini / etc / systemd / ... 'e bırakmanız gerekiyor
vonbrand

Bu günlerde default.targetbulunabilir/lib/systemd/system/default.target
czerasz

1
@czerasz Fedora 27'de fark ettim, eğer systemctl set-default ...bir symlink bırakırsa /etc/systemd/system, ancak birini değiştirmez /lib, yani farklı hedefleri işaret ederler, ancak önceki şeyleri ikincisini geçersiz kılmalıdır. Eğer kendiniz koyarsanız, olabilecekler budur. Her neyse, her iki yerde de düzenleme yaptım.
goldilocks

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.