Perbedaan antara systemd dan program awal terminal

9

Saya ingin tahu apa perbedaan antara program yang ada; dimulai dengan systemd ketika diaktifkan melalui systemctl, vs yang dimulai dengan /etc/rc.localatau melalui CLI.

Sebagai contoh, saya baru-baru ini menggunakan shairport-sync untuk pi raspberry. Awalnya, saya mengatur shairport-sync untuk memulai dengan cara sudo systemctl mengaktifkan shairport-sync.

Kemudian di jalan saya menggunakan fungsi di dalam shairport-syncuntuk menjalankan skrip sebelum dan mengirim ke perangkat yang terhubung.

Yang mengejutkan saya, skrip ketika dieksekusi oleh shairport-synctidak kill arecordatauaplay

Namun, ketika saya akan menjalankan skrip melalui terminal skrip dieksekusi dan dibunuh arecorddan aplay.

Untuk lebih membingungkan diri saya, saya membunuh shairport-syncdan memulainya melalui terminal untuk melihat hasil dari apa yang terjadi. Ketika saya melakukannya skrip berfungsi seperti yang saya harapkan ketika perangkat terhubung dan membunuh arecorddan aplay. Jadi, sebagai memperbaiki saya dinonaktifkan shairport-syncdi sysmtectldan mengaturnya untuk berjalan dalam /etc/rc.localsebagai perbaikan cepat. Setelah rebootitu berfungsi seperti yang saya harapkan.

Hal ini membuat saya percaya bahwa ada beberapa perbedaan antara program yang dijalankan sebagai bagian dari systemddan program yang berjalan ketika dimulai melalui /etc/rc.localatau CLI.

Mengapa ini terjadi? Apakah ini karena level run yang berbeda? Beberapa sihir gelap?

Skrip yang dijalankan saat perangkat terhubung shairport-syncadalah sebagai berikut:shairportstart.sh

#!/bin/sh
/usr/bin/sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
        /usr/bin/amixer set Speaker 40%
else
        /usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&

exit 0

Berikut ini skrip fade: shairportfade.sh

#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do  
    /usr/bin/amixer set Speaker 1+
done
exit 0

Skrip yang dijalankan saat perangkat terputus shairport-syncadalah sebagai berikut:shairportend.sh

#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0

Saya menemukan kesalahan berikut di /var/log/sysloghanya ketika shairport-sync awalnya dijalankan terpisah systemd. Kapan shairport-syncdijalankan dari CLI atau /etc/rc.localtidak ada kesalahan hadir.

Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified

Harap dicatat, bahwa satu-satunya perbedaan adalah bagaimana shairport-syncawalnya dimulai, ketika perangkat terhubung atau terputus shairport-syncterus berjalan.

Brett Reinhard
sumber
1
Itu ps ... awk ... grep ...hal mungkin diganti dengan sederhanapkill
thrig
@ Thrig awalnya garisnya jauh lebih sederhana tetapi karena tidak berfungsi atau jadi saya pikir saya mencoba menggunakan metode lain untuk membunuh contoh yang masih tidak berfungsi. Membunuh proses itu bukan masalah semata, karena berhasil tetapi hanya ketika dijalankan dari login pengguna
Brett Reinhard
dapatkah Anda menunjukkan daftar /home/pi/shScripts/shairportfade.sh?
Michael D.
@MichaelD. saya telah menambahkan skrip pudar serta skrip yang dijalankan ketika perangkat terputus untuk sinkronisasi-shairport
Brett Reinhard
@ BrettReinhard apa masalahnya dengan menjalankan skrip darirc.local
Michael D.

Jawaban:

18

Variasi "Mengapa segala sesuatu berperilaku berbeda di bawah systemd?" adalah pertanyaan yang sering diajukan.

Setiap kali sesuatu berjalan dari CLI dan bukan dari systemd, ada beberapa kategori luas kemungkinan untuk menjelaskan perbedaan.

  1. Variabel lingkungan yang berbeda . systemdmendokumentasikan variabel lingkungan yang dilewatinya di man systemd.execbagian variabel Lingkungan dalam proses spawned . Jika Anda ingin memeriksa sendiri perbedaannya, Anda dapat menggunakannya systemd-run /path/to/binary, itu akan menjalankan aplikasi Anda dalam cakupan sementara, karena akan dijalankan oleh layanan systemd. Anda akan mendapatkan output seperti: Running as unit: run-u160.service. Anda kemudian journalctl -u run-u160.servicedapat meninjau output. Ubah aplikasi Anda untuk membuang variabel lingkungan yang diterimanya dan membandingkan menjalankan CLI ke menjalankan systemd. Jika aplikasi tidak mudah dimodifikasi, Anda bisa menggunakan systemd-run envuntuk melihat variabel lingkungan yang akan diteruskan dan meninjau jurnal yang dihasilkan untuk itu. Jika Anda mencoba memulai aplikasi GUI X11, DISPLAYvariabel lingkungan perlu diatur. Dalam hal itu, pertimbangkan untuk menggunakan fitur "autostart" lingkungan desktop Anda systemd.
  2. Pembatasan sumber daya . Lihat man systemd.resource-controlnilai konfigurasi yang dapat membatasi konsumsi sumber daya. Gunakan systemctl show your-unit-unit.serviceuntuk memeriksa nilai konfigurasi lengkap yang memengaruhi layanan yang Anda coba mulai.
  3. Shell non-interaktif . bashLingkungan CLI Anda adalah shell login interaktif . Ini memiliki file sumber seperti .bashrcitu systemdbelum. Selain mengatur variabel lingkungan, skrip ini dapat melakukan sejumlah hal lain, seperti menghubungkan agen SSH sehingga tindakan SSH tidak memerlukan login. Lihat juga Perbedaan antara Shell Login dan Shell Non-Login?
  4. Tidak TTY . Sesi interaktif Anda terhubung ke TTY yang disukai sudodan sshdiharapkan beberapa program saat meminta kata sandi. Lihat juga sudo: tidak ada tty yang ada dan tidak ada program askpass yang ditentukan
  5. Relatif vs Absolute Paths . Pekerjaan biner relatif di shell, tetapi seperti yang didokumentasikanman systemd.service , argumen pertama ExecStart=harus menjadi path absolut ke biner.
  6. Sintaks baris perintah terbatas . CLIs Shell mendukung banyak metacharacters, sementara itu systemdmemiliki sintaks baris perintah yang sangat terbatas . Bergantung pada kebutuhan Anda, Anda mungkin bisa meniru sintaksis Shell dengan systemdsecara eksplisit menjalankan perintah Anda melalui shell:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'

Ini adalah fitur yang sistem menjalankan kode Anda dalam lingkungan yang konsisten dengan kontrol sumber daya. Ini membantu dengan hasil yang stabil dan dapat direproduksi dalam jangka panjang tanpa membebani perangkat keras.

Mark Stosberg
sumber
Juga perlu mempertimbangkan konteks MAC akun (SELinux, ...), kemampuan, ruang nama ...
Bigon
2
@ BrettReinhard Jangan panggil sudoskrip shell lebih baik dijalankan sudo shairportstart.shdari terminal, karena systemd menjalankan skrip sebagai root, tidak perlu sudo sebagai root.
Michael D.
1
Saya memecahkan masalah saya dengan berbagai cara dalam upaya saya untuk memahami apa yang terjadi. Pada akhirnya, apa yang akhirnya saya lakukan adalah mengubah perintah membunuh saya /usr/bin/echo "mypassword" | /usr/bin/sudo /bin/pkill arecord. Kemudian hari ini, saya akan mencoba menghapus perintah sudodan echountuk membunuh perintah saya dan melihat apakah itu menghasilkan hasil yang sama. Dugaan saya adalah itu akan berfungsi, karena tampaknya kesalahan itu disebabkan oleh tidak ada kata sandi yang dikirim dengan sudoperintah. Terima kasih atas bantuannya dalam memahami mengapa ada perbedaan antara systemddan CLI
Brett Reinhard
1
Satu perbedaan lain, yang mungkin jelas tetapi yang menggigit saya hari ini, adalah bahwa systemd mencoba untuk melacak status suatu layanan dan tidak akan memulainya jika dianggap sudah aktif, sehingga bahkan mungkin tidak meluncurkan skrip init.d jika itu berpikir layanan sedang berjalan. Sebaliknya, skrip init.d biasanya ditulis untuk selalu memeriksa dan mencoba memulai layanan yang sesuai.
Josh Kelley
1
@JoshKelley Terima kasih atas tipnya. Itu bukan perbedaan antara skrip systemd dan CLI tetapi antara skrip systemd dan sysVinit init.d.
Mark Stosberg