Bir komut dosyasını başka bir kullanıcı olarak başlatma


12

/Etc/init.d/ dosyasında, ev dizinlerinden diğer (root ayrıcalı olmayan) kullanıcıların diğer komut dosyalarını çalıştırmış gibi çalıştırmaları gereken bir komut dosyası oluşturdum.

Bu senaryoları aşağıdakilerle başlatırım: sudo -b -u <username> <script_of_a_particular_user>

Ve çalışıyor. Ancak çalışmaya devam eden her kullanıcı komut dosyası için (örneğin bazı bekçi köpeği), hala canlı ve kök olarak çalışan karşılık gelen bir üst sudo işlemi görüyorum. Bu, etkin işlemler listesinde karışıklık yaratır.

Yani sorum şu: Başka bir kullanıcı olarak mevcut bash komut dosyasından başka bir komut dosyasını nasıl başlatabilirim (çatallayabilir) ve artık (tek başına) bir işlem olarak bırakabilirim?

Daha ayrıntılı bir açıklama:
Temelde .startUp ve .shutDown adlı kendi ana dizininde bulunan ilgili alt dizinlerde bulunan yürütülebilir dosyaları çalıştırarak sistemdeki diğer kullanıcılara sistem başlangıcında veya sistem kapatıldığında bir şeyler çalıştırmak için bir araç sağlamaya çalışıyorum. Bunu yapmak için başka bir yol bulamadığım için, tam olarak bunu yapan bash betiğimi yazdım ve /etc/init.d/ içinde bir servis betiği olarak (iskelet örneğini izleyerek) yapılandırdım, böylece çalıştırıldığında start argümanı ile .startUp dizinlerinden her şeyi başlatır ve stop argümanı ile çalıştırıldığında, her kullanıcının tüm .shutDown dizinlerinden her şeyi başlatır.

Alternatif olarak, bu sorunu çözmek için mevcut bir çözümü de kullanabilir miyim?

GÜNCELLEME
Biraz etrafa baktım ve şu soruyu buldum: /unix/22478/detach-a-daemon-using-sudo

Orada kabul edilen cevap, kullanmak için:, sudo -u user sh -c "daemon & disown %1"benim için çalışıyor. Ama % 1'i reddetmeden de denedim ve aynı. Yani beklediğim gibi benim için işe yarıyor:

sudo -u <username> bash -c "<script_of_a_particular_user> &"

Şimdi ek sorum şu: Neden tartışmasız çalışıyor? Bazı özel durumlar için reddetme çağrısını hala bırakmalı mıyım?

GÜNCELLEME 2

Görünüşe göre bu da işe yarıyor:

su <username> -c "<script_of_a_particular_user> &"

Bu çağrı ile sudo çağrısı arasında herhangi bir fark var mı? Bunun potansiyel olarak tamamen farklı bir soru olduğunu biliyorum. Ama burada cevapları kendim bulduğum için belki bu konu uğruna birisi burada açıklığa kavuşabilirdi.

GÜNCELLEME 3
Bu yöntemlerin her ikisi de su veya sudo ile artık makineyi başlattıktan sonra yeni bir startpar işlemi (root olarak çalışan tek işlem) üretiyor . İşlem listesinde şu şekilde görünür:

startpar -f -- <name_of_my_init.d_script>

Bu süreç neden ortaya çıkıyor? Açıkçası ben başka bir init.d komut dosyası bu işlemi çalışan beri yanlış bir şey yapıyorum.

GÜNCELLEME 4
Startpar ile ilgili sorun çözüldü. Bunun için başka bir soru başlattım:
rc.local veya init.d'den işlemleri başlatırken startpar işlemi asılı kaldı.

Ayrıcalıklı olmayan kullanıcılar için başlatma mekanizmalarını daha ayrıntılı tartışmak için başka bir soru:
Normal kullanıcılara (root olmayan) başlatma ve kapatma otomatik çalıştırma yetenekleri sağlama

Yanıtlar:


18

Bunun doğru cevabı, doğru "daemonization" için standart girdi, standart çıktı ve standart hatanın / dev / null (veya bazı gerçek dosyalara) yönlendirilmesi gerektiğiydi:

su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"

su - belirtilen komutu nohup çalıştırmak için someuser
-c - su argümanına kullanıcı kimliğini kullanın -
Hangout'lara karşı bir bağışıklık komutu çalıştırın. Üst sürecin alt süreci sonlandıracağı durumları önlemek. Her ihtimale karşı buraya eklendi. Ama benim özel durumumda aslında bir etkisi yok. Gerekli olup olmadığı ortamda (onay bağlıdır shopt )
> / dev / null temelde devre dışı bırakmayı hiçbir şey yönlendir standart çıkışa, -.
2> & 1 - Standart hata (2) çıkışını null
& - arka plana ayrılmaya yönlendirilen standart çıkışa (1) yeniden yönlendirir , bu standart girişi / dev / null'a da yönlendirir.

Bu aslında Debian dpkg'ın start-stop-daemon programının tam olarak yaptığı şeydir . Bu yüzden kodları başka bir harici yardımcı çağrısı tanıtmak yerine bu şekilde komut dosyalarını başlatmayı tercih ediyorum. start-stop-daemon , başlatmanız gereken tam gelişmiş daemon programlarına sahip olduğunuz ve start-stop-daemon'un sağladığı ek işlevselliğe ihtiyaç duyduğunuz durumlarda yararlıdır (örneğin, belirtilen işlemin çalışıp çalışmadığını kontrol etmek için tekrar başlatmayın).

Ayrıca, işleminizin dosya tanımlayıcılarını / dev / null öğesine yönlendirmek yerine kapatabileceğinizi de belirtmek gerekir; örneğin:

su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"

0 <& - Standart girişi kapat (0)
1> & - Standart çıkışı kapat (1)
2> & - Standart hata (2) çıkışını kapat

<> İşaretlerinin yönü, uzun dosya tanımlayıcı numarası belirtildiği için önemli değildir. Yani bu eşit derecede iyi:

su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"

veya

su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"

Ancak, stdin ve stdout için sayılar olmadan, yönün önemli olduğu yerlerde yazmanın biraz daha kısa bir yolu vardır:

su someuser -c "some_script.sh <&- >&- 2>&- &" 

Dosya tanımlayıcıları kapatıldığında veya / dev / null'a yönlendirildiğinde ( start-stop-daemon / dev / null dizinine yeniden yönlendirme yapıyorsa), işlem arka planda bir daemon olarak çalışabilir. Öyleyse, önyükleme süresi boyunca komut dosyalarını başlatma ile ilgili sorunları ( startpar ) önlemek için gereken budur .

Tüm çözümü ilk fikrimden uyguladım ve GitHub'a yerleştirdim:
https://github.com/ivankovacevic/userspaceServices


Ivan, su veya su -login kullanmak daha mı iyi? Su adamını okudum ama bu özel durumu anlayamıyorum.
Massimo

1
@Massimo, cevabımdaki gecikme için özür dilerim! Bu soruya bir göz atın: unix.stackexchange.com/questions/318572/… orada açıklayan daha iyi bir manuel sayfa var. Temel olarak fark çalışma dizini ve ortam değişkenlerinin ayarlanmasıdır. Bunun gibi kullanım durumları için söyleyebilirim (başka bir kullanıcı olarak bir şey yapmak) aslında -login kullanmak için tercih edilen bir seçenek olabilir
Ivan Kovacevic


2

Bunu tam olarak test etmedim, ama böyle bir şey olduğunu düşünüyorum:

/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile

başlangıçta ve sonra

/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid

kapatırken.

.ShutDown komut dosyasının işlenmesi, başlatma işlemi gibi bir şey tarafından yapılabilir, ancak kapatma işleminin yine de gerçekleşmesi gerektiğinden komut dosyalarının sona erdiğinden emin olamazsınız :-)

hile yapmalı, belki bazı giriş yönlendirmeleri atmalısınız, ancak daha sonra günlük dosyalarının doldurulması konusunda endişelenmeniz gerekir.


2
Esasen, bu işe yarar! start-stop-daemon, önyüklemede veya başka bir şekilde işlemleri başarıyla başlatabilir. Test ettim. Ayrıca asıl startpar işlemiyle bu problemden de kurtulur. Ancak başlangıç ​​çağrınızda bir --chuid USER eksik. Onsuz, süreci kök olarak başlatırdı. Pid dosyası da muhtemelen / var / run / dizinine yazılmalıdır, aksi takdirde kullanıcılar giriş dizininde kök dosya oluşturur. Ancak, bence, genel komut dosyası için start-stop-daemon'u başlatmak biraz aşırıya kaçmış gibi görünüyor. Nedenini ayrıntılı olarak anlatmaya çalıştığım yanıtı kontrol edin.
Ivan Kovacevic

1

Kullanmayı denedin sumi?

su -c /home/user/.startUp/executable - user

-c su'ya komutu yürütmesini söyler ve son parametre kullanıcı olarak komutu çalıştırmasıdır.


evet, bu işe yarar ama bazı tırnak ve ve işareti eklendi. Ve ben böyle yazmak daha temiz buluyorum: su <kullanıcı adı> -c "/some/path/script.sh &" Temelde sudo kullandım çünkü temiz gibi görünüyordu ama şimdi bu daha sonra kullanmak daha iyi görünüyor: sudo - u <kullanıcı adı> bash -c "/some/path/script.sh &". Bu ikisi arasında herhangi bir fark olup olmadığını bilmiyorum
Ivan Kovacevic
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.