Zaten uzun süredir devam eden bir süreç var ve bitirmek istemiyorum.
Nohup altına nasıl koyabilirim (yani, terminali kapatsam bile çalışmaya devam etmesini nasıl sağlayabilirim?)
Zaten uzun süredir devam eden bir süreç var ve bitirmek istemiyorum.
Nohup altına nasıl koyabilirim (yani, terminali kapatsam bile çalışmaya devam etmesini nasıl sağlayabilirim?)
Yanıtlar:
İşlemi arka plana göndermek için bash'ın İş Denetimini kullanma :
bg
arka planda çalıştırmak için.disown -h [job-spec]
burada [job-spec] iş numarasıdır ( %1
ilk çalışan işte olduğu gibi; jobs
komutla numaranızı bulun ), böylece terminal kapatıldığında iş öldürülmez.disown -h
olduğu için , belki de daha kesin bir cevaptır: "reddetme daha çok nohup gibi davranır (yani kabuktan çıkana kadar işler mevcut kabuğunuzun işlem ağacında kalacaktır) Bu görmenizi sağlar bu merminin başladığı tüm işler. " ([ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… adresinden )
disown
, disown bir işlemi bir artalan programı haline getirdikten sonra bir işin çıktısını göremezsiniz, yani standart girdi / çıktı / dev / null'a yönlendirilir. Bu nedenle, bir işi reddetmeyi planlıyorsanız, bir dosyaya giriş my_job_command | tee my_job.log
disown
boruları işlemden ayırır. Boruları yeniden takmak için bu ipliktegdb
açıklandığı gibi kullanın . Daha spesifik olarak, bu yazı .
Herhangi bir nedenle Ctrl+ ' Znın da çalışmadığını varsayalım , başka bir terminale git, işlem kimliğini bul (kullan ps
) ve çalıştır:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
işlemi askıya alır ve SIGCONT
arka planda işleme devam eder. Şimdi, her iki terminalinizi de kapatmak işleminizi durdurmayacak.
disown %1
Kapatmadan önce ilk terminalde yapmayı unutmayın .
kwin
bir çarpışmadan sonra sonuçları düşünmeden konsole başladım ). Yani eğer kwin'i durdursaydım, her şey donmuş olacaktı ve koşma imkanım yoktu bg
!
Çalışan bir işi kabuktan ayırma komutu (= bunu nohup yapar) disown
ve temel bir kabuk komutudur.
Bash-manpage'den (man bash):
reddetme [-ar] [-h] [jobspec ...]
Seçenekler olmadan, her jobpec aktif işler tablosundan kaldırılır. -H seçeneği belirtilirse, her jobpec öğesi tablodan kaldırılmaz, ancak kabuk SIGHUP alırsa SIGHUP işe gönderilmeyecek şekilde işaretlenir. Hiç jobpec yoksa ve ne -a ne de -r seçeneği sağlanmazsa, geçerli iş kullanılır. Hiç jobpec sağlanmazsa, -a seçeneği tüm işleri kaldırmak veya işaretlemek anlamına gelir; jobspec bağımsız değişkeni olmadan -r seçeneği, işlemi çalışan işler ile sınırlar. Jobspec geçerli bir iş belirtmedikçe, dönüş değeri 0'dır.
Bu, basit bir
disown -a
tüm işleri iş tablosundan kaldıracak ve onları nohup yapacak
disown -a
tüm işleri kaldırır. Basit bir işlem disown
yalnızca geçerli işi kaldırır. Cevaptaki man sayfasının söylediği gibi.
Bunlar yukarıdaki iyi cevaplar, sadece bir açıklama eklemek istedim:
disown
Bir pid veya işlem yapamazsınız, bir işsiniz disown
ve bu önemli bir ayrımdır.
Bir iş, bir kabuğa bağlı bir süreç kavramı olan bir şeydir, bu nedenle işi arka plana atmanız (askıya almamanız) ve daha sonra reddetmeniz gerekir.
Konu:
% jobs
[1] running java
[2] suspended vi
% disown %1
Unix İş Denetiminin daha ayrıntılı bir tartışması için http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ adresine bakın .
Ne yazık ki disown
bash'a özgüdür ve tüm kabuklarda mevcut değildir.
Unix'in bazı tatları (örn. AIX ve Solaris), nohup
komutun kendisinde çalışan bir işleme uygulanabilecek bir seçeneğe sahiptir:
nohup -p pid
AIX
ve için Solaris
. Msgstr "Nohup'un AIX ve Solaris sürümlerinde, çalışmakta olan bir işlemi gelecekteki SIGHUP sinyallerini yok saymak için değiştiren bir -p seçeneği vardır. Kaynak
Düğümün cevabı gerçekten harika, ama stdout ve stderr'in nasıl yeniden yönlendirilebileceği sorusunu açık bıraktı. Unix ve Linux'ta bir çözüm buldum , ancak tamamlanmadı. Bu iki çözümü birleştirmek istiyorum. İşte burada:
Testim için loop.sh adlı küçük bir bash betiği yaptım, bu da pid'i sonsuz bir döngüde bir dakika uyku ile bastı.
$./loop.sh
Şimdi bu işlemin PID'sini bir şekilde alın. Genellikle ps -C loop.sh
yeterince iyidir, ancak benim durumumda yazdırılır.
Şimdi başka bir terminale geçebiliriz (veya ^ Z ve aynı terminalde tuşuna basabiliriz). Şimdi gdb
bu sürece eklenmelidir.
$ gdb -p <PID>
Bu komut dosyasını durdurur (çalışıyorsa). Durumu ps -f <PID>
, STAT
alanın 'T +' olduğu (veya ^ Z 'T' olması durumunda) ile kontrol edilebilir, yani (adam ps (1))
T Stopped, either by a job control signal or because it is being traced
+ is in the foreground process group
(gdb) call close(1)
$1 = 0
Kapat (1) başarı durumunda sıfır döndürür.
(gdb) call open("loop.out", 01102, 0600)
$6 = 1
Open (1), başarılı olursa yeni dosya tanımlayıcısını döndürür.
Bu açık eşittir open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
. Bunun yerine O_RDWR
O_WRONLY
uygulanabilir, ancak /usr/sbin/lsof
tüm std * dosya işleyicileri ( FD
sütun) için 'u' diyor , yani O_RDWR
.
/Usr/include/bits/fcntl.h başlık dosyasındaki değerleri kontrol ettim.
Çıktı dosyası ile açılabilir O_APPEND
gibi nohup
yapacağını, ancak bu önerdiği edilmez man open(2)
çünkü olası NFS problemleri.
Dönüş değeri olarak -1 alırsak call perror("")
, hata iletisini yazdırır. Errno'ya ihtiyacımız olursa, p errno
gdb comand kullanın .
Şimdi yeni yönlendirilen dosyayı kontrol edebiliriz. /usr/sbin/lsof -p <PID>
baskılar:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
İstersek, stderr'ı başka bir dosyaya yeniden yönlendirebiliriz, eğer başka bir dosya adı kullanarak call close(2)
ve call open(...)
tekrar kullanırsak.
Şimdi ekteki bash
serbest bırakılmalıdır ve bırakabiliriz gdb
:
(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q
Komut dosyası gdb
başka bir terminalden durdurulmuşsa çalışmaya devam eder. Loop.sh'nin terminaline geri dönebiliriz. Şimdi ekrana hiçbir şey yazmıyor, dosyaya çalışıyor ve yazıyor. Bunu arka plana koymalıyız. Yani basın ^Z
.
^Z
[1]+ Stopped ./loop.sh
(Şimdi ^Z
başlangıçta basıldığımız durumdayız .)
Şimdi işin durumunu kontrol edebiliriz:
$ ps -f 24522
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
$ jobs
[1]+ Stopped ./loop.sh
Bu yüzden süreç arka planda çalışmalı ve terminalden ayrılmalıdır. jobs
Komutun çıktısındaki köşeli parantez içindeki sayı, içindeki işi tanımlar bash
. bash
İş numarasından önce '%' işareti uygulayarak aşağıdaki yerleşik komutlarda kullanabiliriz :
$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
Ve şimdi çağıran bash'tan çıkabiliriz. İşlem arka planda çalışmaya devam eder. PPID'den ayrılırsak 1 (init (1) işlemi) olur ve kontrol terminali bilinmez olur.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted)
loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,36 38 /dev/pts/36 (deleted)
YORUM YAP
Gdb öğeleri otomatik olarak komutları içeren bir dosya (ör. Loop.gdb) oluşturabilir ve çalıştırılabilir gdb -q -x loop.gdb -p <PID>
. Benim loop.gdb şöyle görünür:
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
Ya da bunun yerine aşağıdaki bir astar kullanılabilir:
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
Umarım bu çözümün oldukça eksiksiz bir tanımıdır.
lsof
(dosya tanıtıcısının adı pipe
gibi değil /dev/pts/1
) veya tarafından ls -l /proc/<PID>/fd/<fd>
(bu tanıtıcı sembolik bağlantısını gösterir ) yönlendirilip yönlendirilmediğini denetleyebilirsiniz . Ayrıca, alt süreçler yine de bir dosyaya yeniden yönlendirilmesi gereken çıkışları yeniden yönlendiremez.
Çalışan işlemi nohup'a göndermek için ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
, benim için çalışmadı
Sonra aşağıdaki komutları denedim ve çok iyi çalıştı
Biraz SOMECOMMAND yönetin /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.
Ctrl+ Zprogramı durdurmak (duraklatmak) ve kabuğa geri dönmek için.
bg
arka planda çalıştırmak için.
disown -h
böylece terminal kapandığında süreç öldürülmez.
Kabuktan exit
çıkmak için yazın çünkü artık işlem kendi işleminde arka planda çalışacağı için gitmeye hazırsınız, bu yüzden bir kabuğa bağlı değil.
Bu işlem koşmaya eşdeğerdir nohup SOMECOMMAND
.
bg
- Bu işin arkaplanını ve çalışma sürecine geri dönmesini sağlardisown -a
- bu, tüm eki iş ile keser (böylece terminali kapatabilirsiniz ve yine de çalışır)Bu basit adımlar, işlemi devam ettirirken terminali kapatmanıza olanak tanır.
Yapmayacak nohup
(sorunuz hakkındaki anlayışım temelinde, burada buna ihtiyacınız yok).
Bu benim için tcshell iken Ubuntu linux üzerinde çalıştı.
CtrlZ duraklatmak için
bg
arka planda çalıştırmak
jobs
iş numarasını almak için
nohup %n
burada n iş numarasıdır
nohup: failed to run command '%1': No such file or directory
yourExecutable &
yazıp çıktılar ekranda gelmeye devam ediyor veCtrl+C
hiçbir şey durmuyor gibi görünse de , ekran çıktılarla kaydırılsa bile körü körüne yazındisown;
ve basınEnter
ve yazıyorsun. İşlem reddedilecek ve işlem ölmeden terminali kapatabileceksiniz.