Neden bazı komutlar terminali bitinceye kadar 'kapatıyor'?


22

Bazen, diyelim ki, terminalden bir programı çalıştırmak lxpanel . Terminal sizi istemine bırakmayacak, askıda kalacak. Bilgi istemine geri dönmek için Ctrl+ tuşuna basabilirsiniz C, ancak bu ölecektir lxpanel. Bununla birlikte, Alt+ ' ya basıldığında F2(komut almak için bir pencere açılır) ve çalıştırma lxpaneldüzgün bir şekilde çalışır.

Bu neden? Terminalden bir komut çalıştırmakla Alt+ tuşuna bastığınızda görünen 'run' penceresinden farklı olan ne F2?

lxpanel burada sadece bir örnek olarak kullanılmıştır. Bunu birden fazla programla yaşadım


1
İpucu: GNU Screen ( screen), diğer şeylerin yanı sıra, daha uzun süren işlemleri "sarmak" için kullanılabilir. Ondan ayrılabilir, kabuğa geri dönebilir, ardından yeniden takıp çalışan işlemin çıktısını görebilirsiniz. Yeniden ekleme, başka bir terminalden, SSH'den bile yapılabilir. Bu tür bir şeyi yapmanıza izin veren başka programlar da olabilir.
poplitea

Yanıtlar:


28

Terminal, varsayılan olarak programı ön planda çalıştıracak, böylece program bitene kadar kabuğa geri dönmeyeceksiniz. Bu, stdin'den okuyan ve / veya stdout'a yazan programlar için kullanışlıdır - genellikle çoğunun aynı anda çalışmasını istemezsiniz. Bir programın arka planda çalışmasını istiyorsanız, aşağıdaki şekilde başlatabilirsiniz:

$ lxpanel &

Veya zaten çalışıyorsa, Ctrl+ ile askıya alabilir ve arka plana taşımak için Zkoşabilirsiniz bg. Her iki durumda da yeni bir kabuk istemi ile sonuçlanacaksınız, ancak program hala çalışıyor ve çıktısı terminalde görünecek (yazmanın ortasındayken aniden görünebilir)

Bazı programlar (tipik olarak ödemeler) başlatıldıklarında ayrı bir işlem gerçekleştirir ve ardından ana işlemin hemen çıkmasına izin verir. Bu, programın kabuğunu engellemeden çalışmaya devam etmesini sağlar


Peki Alt + f2 tuşlarına basarak programı 'çalıştır' penceresinden çalıştırdığınızda aslında sistem ne yapıyor? (en azından cüceler ve openbox'larda alt + f2 bunu yapar). Soruyorum çünkü komutu yazdığınız anda program başlar ve kutu kaybolur. sadece bir & ekliyor mu?
sqram

2
@lyrae: varsayılan olarak, kabuk, kabuk oturumuna devam etmeden önce programın tamamlanmasını bekler, "askıya alma" herhangi bir "askıya alma" tanımıyla olmaz; alt + f2 programı beklemiyor. Kabuğun programın tamamlanmasını beklemesinin nedeni, kabuğun, kullanıcının kabuğuna yazdığı her şeyi programın standart girişine ve / veya programın standart çıkışına yönlendirebilmesidir. Alt + f2 öncelikle bir GUI programı başlatmak için kullanıldığından, alt + f2 standart giriş / çıkış kullanma imkanı sağlamaz ve bu nedenle beklemesi gerekmez.
Yalan Ryan

1
@ lyrae: alt + f2 programı arka planda başlatmak için özel bir şey yapmaz; özel bir şey yapan kabuktur, '&' eklemek kabuğun işlevselliğidir. '&' İşareti olmayan bir komut başlattığınızda , kabuk programın standart girişini kendi standart girişine ve programın standart çıkışını kendi standart çıkışına (kabuk da Ctrl'nin yakalanması gibi diğer birçok hizmeti de sağladığından, bir miktar doğrulanır) yönlendirir. -C, ön plan programına SIGINT sinyal komutu göndermek için). '&' Kabuğa bunları yapmamasını ve sadece programı başlatmasını söyler.
Yalan Ryan

1
@LieRyan, kabuğun yaptığı şeylerin bir kısmı aslında çekirdeğin terminal sürücüsü tarafından gerçekleştirilir ve "with &" genellikle "olmadan &" ile "kabuğundan" beklediğinizden daha "özel" olur () [veya Alt-f2 tarafından yapılmamış olan waitpid ya da eşdeğeri].
Random832

6

Bir terminalde bir program başlattığınızda, programınız durana kadar terminal "askıda kalacaktır". Ctrl+ Tuşlarına basarak c, programınızı kapatıyorsunuz ve bu sayede isteme geri dönüyorsunuz. Bunu tüm GUI uygulamalarında göreceksiniz, örneğin Firefox'u deneyin.

Alt + F2 gibi başka bir yöntem kullandığınızda veya menüleri tıkladığınızda, programınız arka planda başlatılır, böylece tuhaf bir şey olmaz (ve yine de komut istemi yoktur).

GUI uygulamalarını hala terminalden başlatmak istiyorsanız &, komutunuzun sonuna ekleyin .

lxpanel &

Bu, terminale lxpanelarka planda çalışmasını ve size hemen bir kez daha komut vermesini söyler .


3

Programlar, varsayılan olarak bir kabuğun ön kısmındaki bir kabuk aracılığıyla çalışır. Bu, kabuğun çalışmayı askıya almasına ve terminalden programa stdin / stdout / sterr'ye yönlendirmesine neden olur. Masaüstü ortamı üzerinden çalışan programlar , bu programları çalıştıran programdan bağımsız olarak çalıştırmalarına neden olacak şekilde çatallanır . Bu &, komutlara a ekleyerek çoğu kabukta simüle edilebilir , ancak yine de std *'yi terminale bağlayacaktır (arka planlı bir programda stdin'den okunması başka komplikasyonlara sahip olsa da).


2

Daha sonra konsol etkileşimine ihtiyaç duyan programlar dışında kalanlar (örneğin, kullanıcının gerçekten "gerçekten zorla mı?" Sorusunu sormak istediği için STOP durumuna giren "apt -y update"; .... artık kimse izlemiyorsa).

Bu deliği tıkamak ve süreci bir terminal asla asla kullanılamayacak şekilde bilgilendirmek için komutlarımın bazılarına <& - ekliyorum, onları aktif terminalden tamamen ayırmak STDIN'e artık mümkün olmadığını söylüyor. Eğer kullanıyorsanız / bin / bash'ın kabuğunuz olduğundan emin olun. Senaryo, herhangi bir istemi yayınlamak için mevcut olan hiçbir psödoterminal ile ilgili olmayan herhangi bir hatayı günlüğe kaydetmeye devam edecektir.

Örneğin:

`./runme.sh &> runme.log <&- & disown`

Mevcut terminal oturumundan ayrılmamın en iyi yoludur. Hem STDOUT hem de STDERR runme.log'a giriş yapar, konsolunuzun veya kabuğunuzun daha erken bitip bitmemesi veya farklı bir hesaba oturum açmanız / susturmanız (runme'dan terminal çöpü olmaması) ve ebeveyn-çocuktan ayrılmanız sayesinde bir önemi yoktur. PID ilişkisi kaldırıldı.

GÜNCELLEME: Ben bile bir semafor ile orijinal ebeveynin adı ile ilişkilendirerek sorun yaşadım, bu yüzden şimdi tavsiye ederim:

at now <<< "(cmd1; cmd2; etc.) &> logfile.log"

Elbette, çıktıyı CRON'dan e-posta ile göndermek istiyorsanız &> işaretini kaldırın ya da hepsini bir dosya yerine / dev / null dizinine yönlendirin.


Kullanmaya başladım elde etmek için biraz daha az kıvrımlı bir yolat now <<< "(cmd1; cmd2; etc.) &> logfile.log"
Marcos
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.