Bir terminali ayrılmış bir işleme nasıl bağlarım?


99

Terminalimden bir süreci ayırdım, şöyle:

$ process &

Bu terminal şimdi uzun kapalı, ancak processhala çalışıyor ve ben bu işlemin stdin'ine bazı komutlar göndermek istiyorum. Mümkün mü?



Yanıtlar:


112

Evet öyle. İlk olarak, bir boru oluşturun: mkfifo /tmp/fifo. İşleme eklemek için gdb kullanın: gdb -p PID

Sonra stdin'i kapatın call close (0):; ve tekrar açın:call open ("/tmp/fifo", 0600)

Son olarak, bir yere not edin (gdb muhtemelen askıda kalacağı için farklı bir terminalden):

echo blah > /tmp/fifo


6
Çok etkileyici!
Samuel Edwin Ward

1
İşlem stdout'u bir dosyaya yönlendirmek için benzer bir şey yapabilir miyim?
rustyx

@ rustyx: Denenmemiş, ancak bu çalışması gerekir: bir boru yerine bir dosya oluşturun touch /tmp/thefile,. Stdout 1'dir call close (1); Ayrıca, yazmak için doğru izinlere kullanın: call open ("/tmp/thefile", 0400). echo…Deyişle, elbette, gerekli değildir.
Ansgar Esztermann

Bu harika! Bunu, tamamen ayrılmış olan belirli işlemlere "y" veya "n" yanıtları göndermek için kullanıyorum. Ayrılmış işlem, ayrı bir pencereye stdout sahiptir. Bununla birlikte, bu numarayı yaptığımda, yankı çıkardığım anda "y" veya "n" almadığını görebiliyorum, gdb'yi bırakmalı ve ayırmalıyım ve sonra buna göre tüm yankıları aldım. Bunu, işlem beşinci girdiden almadan önce gdb'den çıkmaya gerek kalmadan bunu gerçekleştirmenin bir yolu var mı?
krb686

ne yazık ki, sadece asılı görünüyor call open("/tmp/fifo", 0600). herhangi bir yardım çok takdir edilecektir
okçu

27

Orijinal terminale artık erişilemediğinde ...

reptyristediğiniz ne olabilir, bkz. https://serverfault.com/a/284795/187998

Oradan alıntı:

Tam olarak yapan reptyr'e bir bakın . Github sayfası tüm bilgilere sahiptir.

reptyr - "Yeniden ptying" programları için bir araç.

reptyr mevcut çalışan bir programı alıp yeni bir terminale eklemek için bir yardımcı programdır. Ssh üzerinden uzun süredir devam eden bir süreç başlattım, fakat ayrılmak zorunda kalmak zorunda değil miyiz? Sadece bir ekran başlatın, onu almak için reptyr kullanın ve ardından ssh oturumunu öldürün ve eve gidin.

KULLANIM

reptyr PID

"reptyr PID" id PID ile işlemi kapar ve mevcut terminalinize ekler.

Eklemeden sonra, işlem ^ C ve ^ Z de dahil olmak üzere yeni terminale girdi alır ve çıktı yazar. (Ne yazık ki, arkaplanı yaparsanız, eski terminalde hala "bg" veya "fg" çalıştırmanız gerekecektir. Bu, kabuğunuzu eklemeden makul bir şekilde düzeltmek imkansızdır.)


12

Yapamayacağınıza eminim.

Kullanarak kontrol edin ps x. Bir işlemin tty'yi kontrol ettiği? gibi bir işlem varsa, artık ona girdi gönderemezsiniz.

9942 ?        S      0:00 tail -F /var/log/messages
9947 pts/1    S      0:00 tail -F /var/log/messages

Bu örnekte, 9947benzer şeyler yapmak için girdi gönderebilirsiniz echo "test" > /dev/pts/1. Diğer işlem ( 9942) erişilebilir değil.

Bir dahaki sefere, bu durumu önlemek için ekran veya tmux kullanabilirsiniz.


5
Ya dtachda bir bütüne ihtiyacınız yoksa screen.
Manatwork

4
Orada standartları (POSIX, SUS) hiçbir yolu yoktur, ancak birçok (çoğu?) Sistemlerde bu olduğunu kullanımını hata ayıklayıcıları mekanizmaları kullanarak mümkün. Ansgar'ın cevabına bakınız . Sizinle rootbunu diğer kullanıcıların işlemlerine bile yapabilirsiniz.
dmckee

3
Yapmak echo "test" > /dev/pts/1işlem için girdi göndermez 9947- işlemin terminalinde "test" kelimesini çıkartacaktır.
psmears

6

EDIT : Stephane Gimenez'in dediği gibi, o kadar basit değil. Sadece farklı bir terminale yazdırmanıza izin veriyor.

/ Proc kullanarak bu işleme yazmaya çalışabilirsiniz . / Proc / pid / fd / 0 konumunda bulunmalıdır , bu yüzden basit:

echo "hello" > /proc/PID/fd/0

yapmalı. Denemedim, ancak bu işlem hala geçerli bir stdin dosyası tanımlayıcısına sahip olduğu sürece çalışmalıdır . ls -lOn / proc / pid / fd / ile kontrol edebilirsiniz .

  • Bu / dev / null => bağlantısına sahipse
  • / dev / pts / X bağlantısı veya bir soket => açıksa

İşlemlerin nasıl sürdürüleceği hakkında daha fazla ayrıntı için nohup'a bakın .


2
O kadar basit değil. Örneğin, stdin bir terminale bağlıysa, terminale echobir şey sokmak sadece terminale yazdıklarınızı yazdıracak, prosese iletilmeyecektir.
Stéphane Gimenez

5

Sadece komut satırını sonlandırmak &işlemi tamamen kesmeyecek, sadece arka planda çalıştıracaktır. ( Aslında onu ayırmak için zshkullanabilirsiniz &!, aksi takdirde disowndaha sonra yaparsınız ).

Bir işlem arka planda çalıştığında, artık kontrol terminalinden girdi alamaz. Ancak ile ön plana geri gönderebilirsiniz fgve sonra tekrar girişi okuyacaktır.

Aksi takdirde, dışarıdan (stdin dahil) FileDescriptorları boşaltmanın değiştirmek veya kayıp kontrol terminali yeniden bağlanması için mümkün değildir ... Eğer hata ayıklama araçları (bkz kullanmadıkça Ansgar'ın cevabını veya bir göz rettykomutu).


Ve burada ilgili bir soru var: unix.stackexchange.com/q/17648/9426
Stéphane Gimenez

@Rogach "Bu terminal artık uzun kapalı" dedi.
andcoz

1
@ andcoz: Evet, ancak programın SIGHUPed olmadığı için şanslıydı. Daha güvenli bir yöntem önerdim.
Stéphane Gimenez

Ben ilk olduğu gibi stdout'u yönlendirirseniz burada, inkâr sadece gerçekten çalışıyor >>/dev/stderrben terminali kapattığınızda, "sahiplenmeye" süreç Gerçekten bu tho hiç anlamadım .. de sonun gelecek, aksi halde ..
Kova Güç
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.