Ben `&` kullanıyorum: işlem arka planda neden çalışmıyor?


24

&İşlemi arka planda çalıştırmak için bir komuta ekleyebileceğimi biliyorum .

Ben bir Ubuntu 12.04 kutusuna SSH'ing ve $python program.py &- ile bir python programı çalıştırıyorum - ancak terminal penceresini kapattığımda, terminali kapatmanın çalışan işlemi öldüreceğini söyleyen bir mesaj alıyorum.

Bu neden? İşlemi arka planda çalıştırmak için ve işaretini kullanıyorum. SSH'lı olup olmadığımdan bağımsız olarak çalışmasını nasıl sağlayabilirim?



apt-get install ekran, adam ekranı
captcha

Yanıtlar:


51

Bir terminal penceresini kapattığınızda, terminal emülatörü, çalıştığı işleme, kabuğunuza bir SIGHUP gönderir. Ardından kabuğunuz, bu YAVUZU çalıştığı her şeye yönlendirir. Yerel sisteminizde bu ssh. Ssh daha sonra SIGHUP'ı çalıştığı şeye, uzak kabuğa yönlendirir. Böylece uzak kabuğunuz, arka planlı programınız olan tüm işlemlerine bir SIGHUP gönderir.

Bunun iki yolu var.

  1. Arka plandaki programı kabuktan ayırın.
    1. İşleminizi disownarka planladıktan sonra komutu kullanın . Bu, kabuğun unutmasını sağlayacaktır.
    2. Komutunuzu nohup( nohup $python program.py &) ile önekleyin . Bu aynı şeyi başarır, ancak bir ara işlem kullanarak. Temel olarak, SIGHUP sinyalini görmezden gelir ve sonra ayarı devralan ve sonra çıkan programınızı yönetir ve çalıştırır. Çatallı olduğundan, başlatılan program kabuğun çocuğu değildir ve kabuk bunu bilmiyor. SIGHUP için bir sinyal işleyici kurmazsa, yine de görmezden gelme eylemini sürdürür.
  2. logoutTerminal penceresini kapatmak yerine kullanın . Kullandığınızda logout, bu bir SIGHUP değildir ve bu nedenle kabuk hiçbir çocuğuna bir SIGHUP göndermez.

Ek olarak, programınızın terminale STDOUT veya STDERR üzerinden yazmadığından emin olmalısınız, çünkü ikisi de terminal çıktıktan sonra mevcut olmayacaktır. Bunları bir şeye yönlendirmezseniz /dev/null, program çalışmaya devam eder, ancak bunlara yazmaya çalışırsa, bir SIGPIPE alır ve SIGPIPE'nin varsayılan eylemi, işlemi öldürmektir).


4
Teknik olarak, sshboyama işlemi bağlantının düşmesine, bağlantının düşmesi sshddiğer ucunda ölmeye neden olur . Uzak kabuğun çalıştığı sözde terminalin ana tarafını kontrol eden sshd, öldüğü zaman, bu bir takmadır (tıpkı gerçek bir terminaldeki fişi çekmek gibidir), böylece sistem uzak kabuğa bir SIGHUP gönderir.
Stéphane Chazelas

@ StéphaneChazelas Bu hiç kullanmadığım tek şey. Bunu yapan çekirdekse, hangi işlemi SIGHUP'a nasıl belirler? Açıkça, açık bir dosya tanımlayıcısına sahip olan her şeyi bu TTY'ye göre YAYLADIYOR, çünkü programlar onu kullanmaya çalışmadıkça çalışmaya devam edecektir. Öyleyse şu anda STDIN'den okuyan programı seçiyor mu (bir seferde yalnızca STDIN'den okuyabildiği için)?
Patrick

4
Aldırma, kendi soruma cevap ver. POSIX IEEE 1003.1 bölüm 11, Kontrol terminali için terminal arayüzü tarafından modem bağlantısı kesilirse ... SIGHUP sinyali kontrol işlemine gönderilir .
Patrick

2
Ayrıca , başlattığınız programın çıktısını içeren nohupbir nohup.outdosya oluşturduğunu unutmayın . Bir uygulamayı bu şekilde başlatmak için nohup'u her kullanışınızda (veya çıktısını yeniden yönlendirmeniz gerekebilir) bu dosyayı silmek can sıkıcı olabilir /dev/null.
Ruslan

1
Bunun yerine, derhal programı bırakan yerine nohup python program.py &kullanmanızı setsid python program.pyöneririm.
Hitechcomputergeek

14

İşlem terminaldeki arka planda çalışıyor, ancak stdout(ve stderr) den gelen çıktı hala terminale gönderiliyor. Bunu durdurmak için, her iki çıkışı da yönlendirmek için > /dev/null 2>&1önce ekleyin - ekleme, ayrıca terminali kapattıktan sonra işlemin ölmediğinden emin olur:&/dev/nulldisown

COMMAND > /dev/null 2>&1 & disown

Senin durumunda bu olur:

python program.py > /dev/null 2>&1 & disown

3

&Operatör ayırır komutları gibi, paralel çalışacak şekilde ;ayırır komutları seri olarak çalıştırın. Her iki tür komut da kabuk işleminin bir çocuğu olarak çalışacaktır .

Böylece, bu çocukları başlatan kabuğunu kapattığınızda çocuklar da kapanacaktır.

İstediğiniz gibi görünen şey , önemli ölçüde daha zor olan bir daemon sürecidir çünkü tamamen ana süreçten ayrılması gerekir. Kabuğun genellikle bunu yapmanın basit bir yolu yoktur.


1

Oturumu kapattığınızda, oturum açma oturumu ile ilişkili arka plan işlemleri de normalde öldürülür. Oturumdan bağlantısının kesilmesini istiyorsanız, bunları çalıştırın nohup.

nohup python program.py &

1

Ampersand ( &) ile biten komuttan sonra, komut isteminde şu komutu çalıştırın bg:

bash> python program.py &  
bash> bg  

Bu, "&" komutunu arka plana koyacaktır

bash> jobs  

Bu, arka planda çalışan işleri listeler.

bash> fg 1   

Bu, İş # 1'i ön plana çıkaracak

Başka bir yol, (çıkış yapabilmek için)

bash> at now  
bash> /full/path/python /full/path/program.py  
bash> ^d   `(# That is, Control-D, to run the command, Control-C to cancel)`  

Birden fazla hat sunulabilir at^ d önce, komut (kontrol-D)
bakınız man at.

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.