Neden "su -c <komut> &" bir komutun telefonu kapatmadan arka planda çalışmasına izin veriyor gibi görünüyor


11

Bir arka plan süreciyle ilgili sorunları olan bir meslektaşına aralıklı olarak ölüyordum.

Sunucuda oturum açıp çalıştırarak arka plan işlemine başladıklarını öğrendim:

su - <user> -c '<command>' &

"Aha", diye bağırdım. "&" İle bir komut başlatırsanız, kontrol terminalinden çıktığınızda telefonu kapatır. Bunu başarmak için nohup gibi bir şey kullanmanız gerekir.

Demek istediğimi göstermek için yukarıdaki komutu test ettik ve ... işe yaramış gibi görünüyordu: yukarıdaki komutu çalıştıran terminalden çıktığımızda komutla başlatılan işlem çıkmadı.

command , çıkışı bir dosyaya giden özel bir Python betiğidir. Anlayabildiğim kadarıyla, senaryoda akıllı bir "daemonize" gibi bir yetenek yoktur. Wikipedia: Daemon (hesaplama): Oluşturma sayfasında listelenen bir daemon olarak çalışması için gereken şeylerden hiçbirini yapmaz .

Komutu bu şekilde çalıştırmak beklendiği gibi davranır:

<command> &
exit

Yukarıdaki durumda , terminalden çıktığımızda komut tarafından başlatılan arka plan işlemi çıkar.

Sorum şu:

  1. "Su - -c &" eklediğimizde, terminalimiz çıktığında işlemin çıkmasını önler. Kontrol terminali, standart giriş ve çıkış vb. İle ilgili detaylı olarak anlamak istiyorum.

  2. Bu komutu arka plan işlemi olarak çalıştırma hedefine ulaşmak için makul bir yol mu? Değilse neden, değil mi?

Şirketimdeki en iyi uygulamaları yaymak istiyorum, ancak yaptığım önerileri gösterebilmem ve yedekleyebilmem gerekiyor.

Ayrıca neler olup bittiğini tam olarak anlamak istiyorum.

Yanıtlar:


12

Ölmekte olan bir terminal yüzünden bir sürecin öldürülmesinin birkaç yolu vardır.

  1. Birinci yol çekirdek terminal sürücü olmasıdır bir SIGHUP sinyali gönderir için kontrol işlemi terminal olduğu için kontrol terminali . Çoğu durumda, kontrol işlemi başlangıçta terminalde başlatılan kabuktur ve kontrol terminali stdin, stdout ve stderr'nin bağlandığı terminaldir. Bir işlem çağırırsa kontrol terminali ile bağlantısı kesilir setsid.

  2. İkinci yol, kabuk SIGHUP aldığında, bu sinyali alt süreçlerine, daha kesin olarak arka plan işlerine yeniden göndermesidir. Bazı mermilerin (ksh, bash, zsh) disownmermiye belirli bir işe SIGHUP göndermemesini söyleyecek bir yerleşik vardır.

  3. Terminal giderse ve bir program ondan okumaya çalışırsa, dosya sonu durumu (veya arka plan işi için muhtemelen EIO) bildirilir. Terminal gider ve bir program buna yazmaya çalışırsa, yazma işlemi bir EIO hatasıyla döner. Bunlar programın çıkmasına neden olabilir.

Peki suburada değiştiğine dikkat (2) normalde ilk kabuk arka plan işi öldürmek neden olur, ama bu arka plan işlemi farklı bir kullanıcı olarak çalışan beri, sinyal teslim ve arka plan işlemi yaşamları üzerinde edilemez.


Kök kullanıcı yaptığını gördüm chroot --userspec root:root / sh -c "exec some_forever_process" &. İş aynı kullanıcı olarak çalışıyor, daha nohupönce veya disowndaha sonra açıkça belirtilmemiş . Peki bu durumda, termin çıkışında sinyal nasıl iletilemez?
Toddius Zho

@ToddiusZho Presumable some_forever_processsonsuza kadar çalışacak şekilde tasarlanmıştı (bir daemon) ve böylece SIGHUP'u bir terminal çıkışından (kendi işlem grubunda çalışarak) almaya karşı kendini koruyor.
Gilles 'SO- kötü olmayı bırak'

bash / tail SIGHUP'a karşı koruma sağlamaz, ancak yine de çalışır: `` yerel $ ssh root @ REMOTE_HOST uzak # chroot --userspec root: root / sh -c "exec bash -c 'kuyruk -f / dev / null '"& [1] 6376 uzak # ps -p $! --no-başlık -o pid, uid, komut -ww 6376 0 kuyruk -f / dev / null uzak # çıkış yerel $ ssh root @ REMOTE_HOST uzak # ps -p 6376 - no-başlık -o pid, uid, komut -ww 6376 0 kuyruk -f / dev / null ``
Toddius Zho
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.