Bir işlemi tamamen Terminal'den nasıl ayırabilirim?


304

Ubuntu'da Tilda'yı (açılan terminal) "central central" komutum olarak kullanıyorum - başkalarının GNOME Do, Quicksilver veya Launchy kullanabildiği gibi.

Bununla birlikte, bir sürecin (örn. Firefox) başlatıldığı uçbirimden nasıl tamamen ayrılacağıyla mücadele ediyorum - yani, böyle bir (çocuk olmayan) sürecin önlenmesi

  • kaynak terminali kapatırken sonlandırılıyor
  • kaynak terminali STDOUT / STDERR ile "kirletiyor"

Örneğin, Vim'i "uygun" bir terminal penceresinde başlatmak için, aşağıdaki gibi basit bir betiği denedim:

exec gnome-terminal -e "vim $@" &> /dev/null &

Ancak, bu yine de kirliliğe neden olmaktadır (ayrıca bir dosya adının iletilmesi de işe yaramaz gibi görünmektedir).


1
Bu da iyi bir soru. Sanırım Bash'i bir programlama dili olarak kabul etmenin adil olduğunu düşünüyorum - gerçekte bu sorunun kapsamı muhtemelen sysadmin tarafındadır ...



Kullanım durumunuz başlı başına tam anlamıyla ayrılmayı tanımlamaz.
jiggunjer

Yanıtlar:


344

Her şeyden önce; Bir işlemi başlattıktan sonra, önce durdurup (isabet Ctrl- Z) sonra bgda arka planda devam ettirmek için yazarak arka planı yapabilirsiniz. Şimdi bir "iş" ve stdout/ stderr/ stdinhala terminalinize bağlı.

İşlemin sonuna "&" ekleyerek, hemen arka plandaki bir işlemi başlatabilirsiniz:

firefox &

Susturulmuş arka planda çalıştırmak için şunu kullanın:

firefox </dev/null &>/dev/null &

Bazı ek bilgiler:

nohupUygulamanızı stdout / stderr dosyasının bir dosyaya gönderilebileceği ve ana betiği kapatmanın çocuğu YUKARMAYACAĞI bir şekilde çalıştırmak için kullanabileceğiniz bir programdır . Ancak, uygulamaya başlamadan önce onu kullanma öngörüsünüz olması gerekir. Yolu yüzünden nohupişleri, sadece olamaz Çalışan bir süreç uygulamak .

disownbir kabuk işini kabuğun iş listesinden silen bir bash yerleşimidir. Bunun temel olarak anlamı, artık üzerinde kullanamayacağınız fg, bgancak daha önemlisi, kabuğunuzu kapattığınızda, SIGHUPartık o çocuğa asılmayacağı ya da göndermeyeceğidir . Aksine nohup, işlem başlatıldıktan ve arka plana alındıktan sonradisown kullanılır .

Ne edemez yapmak, bunu başlattıktan sonra bir sürecin stdout'u / stderr / Stdin değiştirmektir. En azından kabuktan değil. İşleminizi başlatır ve stdout'unun sizin terminaliniz olduğunu söylerseniz (varsayılan olarak yaptığınız gibi), o zaman bu işlem terminalinize çıkış yapacak şekilde yapılandırılır. Kabuğunuzun işlemlerin FD kurulumu ile ilgisi yok, bu tamamen sürecin yönettiği bir şey. Sürecin kendisi stdout / stderr / stdin'in kapatılıp kapatılmayacağına karar verebilir, ancak bunu yapmak için kabuğunuzu kullanamazsınız.

Bir arka plan süreci 'çıktısını yönetmek için, muhtemelen akla gelen ilk "nohup" olan betiklerden birçok seçeneğiniz vardır. Ancak etkileşimli işlemler için başlıyorsunuz ama sessizliği unuttum ( firefox < /dev/null &>/dev/null &), gerçekten fazla bir şey yapamazsınız.

GNU’yu almanı öneririm screen. Ekran ile işlem 'rahatsız edici hale geldiğinde yenisini açınca ( ^Ac) yeni çalışan kabuğunuzu kapatabilirsiniz .


Oh, ve bu arada, kullandığın $@yerde " " kullanmayın.

$@anlamına gelir $1, $2, $3..., içine komutu açacak:

gnome-terminal -e "vim $1" "$2" "$3" ...

Muhtemelen istediğin şey bu değildir çünkü -e sadece bir tartışma alır . $1Komut dosyanızın yalnızca bir bağımsız değişkeni işleyebileceğini göstermek için kullanın .

Verdiğiniz senaryoda doğru şekilde çalışan çoklu argümanları elde etmek gerçekten zor ( gnome-terminal -eçünkü), çünkü -ebir kabuk komut dizesi olan tek bir argüman alıyor. Argümanlarınızı birebir kodlamak zorundasınız. En iyisi ve en sağlamı, ama oldukça cansız, yolu şöyle:

gnome-terminal -e "vim $(printf "%q " "$@")"

Bunun için çok teşekkürler! Ne yazık ki sadece bir cevabı kabul edebilirim. "Nohup $ @ &> / dev / null &" ve "alias wvim = 'launch.sh gnome-terminal -x vim'" ile

20
Ne kadar ayrıntılı ve bilgilendirici bir cevap. +1
Teekin

1
@ Etkileşimli bir bash kabuğunu kapattığınızda Hi-Angel, HUP'ların tüm aktif işlerini bash. Bir işlemi ^ Z ve bg yaptığınızda, bu hala bir iş, arka plan olsun. Bir iş olarak kaldırmak için, kullan disown, sonra kabuk artık kapattıktan sonra, kabuğu kapattıktan sonra işlem devam edecek.
lhunath

3
Kullanmayan Will $*yerine $@zaten ayrı dizeleri sorunu çözmek?
sjas

2
Yapamayacağınız şey, başlattıktan sonra bir sürecin stdout / stderr / stdin'ini değiştirmek. - tam olarak doğru değil. Bunun için kullanın reptyr.
Stefan Seidel

198
nohup cmd &

nohup Süreci tamamen çözer (onu küçümser)


5
Özlü değerli olsa da, bütünlük daha değerlidir. Nohup bir GNU coreutil olsa da, burada sadece bash-üstü bir cevap (ya da olmadığına dair not) uygun olacaktır. Yine de iyi cevap.
Sınırlı Kefaret

23
nohupsadece SIGHUPsinyali görmezden geliyor . İşlemi normal şekilde yürütür. Hiçbir şey yapma.
nemo

1
@nemo Bu, işlemin sökülmediği, ancak initkabuk çıkması halinde ayrılmayacağı (ve bir çocuğu ) anlamına gelir ... doğru mu?
Noldorin,

@Noldorin Evet. Kabuk sonlandığında gönderilen SIGHUP'ı dikkate almamak, alt sürecin çalışmasına ve init'e taşınmasına neden olur.
nemo

@nemo nohup ayrıca standart giriş / çıkışları susturur. Tamamen ayırmak için isteksizlikle devam edin.
jiggunjer

60

Kullanıyorsanız bashdeneyin ; bash'a (1) bakınız .disown [jobspec]

Deneyebileceğiniz bir başka yaklaşım at now. Süper kullanıcı değilseniz, kullanma izniniz atkısıtlanabilir.


"disown", bir iç bash komutu gibi görünmüyor (makinemde mevcut değil ve ben bash kullanıyorum). Ben'in önerdiği gibi "nohup" bunu yapmanın çok daha iyi (ve standart) bir yolu olabilir.

1
"at" kullanmayı hiç düşünmedim, fikir için teşekkürler!
cadrian

1
atyürütmeyi başka birine devretmek için, hoşuma gitti! +1
Ninsuo

1
Bir referans noktası olarak, bu da işe yarıyor zsh.
Kodlayıcı

1
Ayrıca, disownistenen etkiye sahip görünmemektedir gnome-terminal- disownsüreçleri hala zaman, terminal çıkış öldürülür ed. Neden / nasıl olduğunu bilmek isterim.
Kyle Strand

38

Bu cevapları okuyarak, yayınlamanın nohup <command> &yeterli olacağı konusunda ilk izlenimdeydim . GNOME terminalinde zsh çalıştırarak, nohup <command> &kabuğumun çıkışta alt süreçleri öldürmesini engellemediğini gördüm. Her ne kadar nohup, özellikle etkileşimli olmayan kabuklarda yararlı olsa da, yalnızca çocuk işlemi SIGHUPsinyal için işleyicisini sıfırlamazsa bu davranışı garanti eder .

Benim durumumda, nohupasılma sinyallerinin uygulamaya ulaşmasını engellemeliydim, ancak alt uygulama (bu durumda VMWare Player) SIGHUPişleyicisini sıfırlıyordu . Sonuç olarak, terminal emülatörü çıktığında, alt işlemlerinizi hala öldürebilir. Bu, ancak sürecin kabuğun iş tablosundan kaldırılmasını sağlayarak bildiğim kadarıyla çözülebilir. Eğer nohupdurum bazen olduğu gibi, bir kabuk yerleşiği ile geçersiz kılınır öyle olmadığını, bu olay, ancak, yeterli olabilir ...


disownbir kabuk içinde yerleşik olan bash, zshve ksh93,

<command> &
disown

veya

<command> &; disown

tek gömlekleri tercih ederseniz. Bu, alt işlemin iş tablosundan çıkarılmasının genel olarak arzu edilen etkisine sahiptir. Bu, çocuk emeğine yanlışlıkla herhangi bir sinyal vermeden terminal emülatöründen çıkmanıza olanak sağlar. SIGHUPİşleyicinin nasıl göründüğü önemli değil, bu çocuğunuzun sürecini öldürmemelidir.

Yok etme işleminden sonra, süreç hâlâ terminal emülatörünüzün bir çocuğu ( pstreebu eylemi izlemek istiyorsanız oynayın ); Başka bir deyişle, her şey olması gerektiği gibi ve muhtemelen olmasını istediğiniz gibi.

Eğer kabuğunuz desteklemiyorsa ne yapmalı disown? Bunu yapmayı şiddetle tavsiye ediyorum, ancak bu seçeneğin yokluğunda, birkaç seçeneğiniz var.

  1. screenve tmuxbu problemi çözebilirler, fakat bunlar çok daha ağır ağırlık çözümleri ve ben onları bu kadar basit bir iş için çalıştırmaktan hoşlanmıyorum. Tipik olarak uzak bir makinede bir tty'i korumak istediğiniz durumlar için çok daha uygundurlar.
  2. Birçok kullanıcı için, kabuğunuzun zsh'ler gibi bir yeteneği destekleyip desteklemediğini görmek istenebilir setopt nohup. Bu SIGHUP, kabuk çıkarken işler tablosundaki işlere gönderilmemesi gerektiğini belirtmek için kullanılabilir . Bunu kabuktan hemen çıkmadan önce uygulayabilir ya da ~/.zshrcher zaman istiyormuş gibi kabuk yapılandırmasına ekleyebilirsiniz .
  3. İşler tablosunu düzenlemenin bir yolunu bulun. Bunu yapmak için tcshya cshda biraz rahatsız edici bir yol bulamadım .
  4. Çatal ve küçük bir C programı yazın exec(). Bu çok kötü bir çözüm, ancak kaynak sadece birkaç düzine çizgiden oluşmalı. Daha sonra komutları C programına komut satırı argümanları olarak iletebilir ve böylece işler tablosuna özel işlem girişlerinden kaçınılabilirsiniz.

29
  1. nohup $COMMAND &
  2. $COMMAND & disown
  3. setsid command

2 numarayı çok uzun zamandır kullanıyorum, fakat 3 numara da aynı şekilde çalışıyor. Ayrıca, disownbir nohupbayrağı vardır -h, tüm işlemleri -akaldırabilir ve çalışan tüm işlemleri kaldırabilir -ar.

Susturma ile gerçekleştirilir $COMMAND &>/dev/null.

Bu yardımcı olur umarım!


Kısa ve güzel; bu çok yararlı özeti için teşekkürler!
Sheljohn

Bu yazı için hala bildirimler aldığımı sanmıyorum ...
Bay Minty Fresh

9

Bence ekran problemini çözebilir.


9

tcsh içinde (ve belki diğer kabuklarda da), işlemi kesmek için parantez kullanabilirsiniz.

Bunu karşılaştırın:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

Buna:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

Bu, firefox'u iş listesinden siler, ancak hala terminale bağlı; Bu düğüme 'ssh' ile giriş yaptıysanız, oturumu kapatmaya çalışmak hala ssh işlemini askıda bırakacaktır.


9

Bash için en basit ve tek doğru cevap:

command & disown

İşlemi terminalden değil kabuktan ayırmanız gerekmez.


7

Tty kabuğunu ayırmak için, örneğin;

(Komut)

Çıkış kullanıldığında terminal kapalı fakat işlem halen canlı.

Kontrol -

(sleep 100) & exit

Diğer terminali aç

ps aux | grep sleep

İşlem hala hayatta.


Bu tam ihtiyacım olan şeydi. Sublime metin için bir konsol kısayolu eklemeye çalışıyordum ve mükemmel bir şekilde çalışıyor, işte sonuçlandığım şey: ("/ opt / Sublime Text 2 / sublime_text" $ @) &
Ron E

5

Bir işin arkaplanı ve ön planlaması muhtemelen her Unix sistem yöneticisinin bilmesi gereken ilk şeylerden biridir.

İşte bash ile nasıl yapılır:

./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg

4

Nohup komutunu kullanarak komutunuzu çalıştırabilirsiniz, bu işleminizi keser ve çıktıları verilen bir dosyaya yönlendirir ... ama tam olarak ihtiyacınız olan şey olduğundan emin değilim.


Nohup gnome-terminal -e "vim $ @" &> / dev / null &: böyle işliyor olarak, ama görünüşe göre değil düzgün - Ben exec kullanmadan önce nohup çalıştı yemin edebilirim

2

Daemon'u deneyin - dost paket yöneticinizden alınmalı ve terminalden ayrılmanın her yolunu kapsamlı bir şekilde ele almalısınız.


2

Bunu bashrc / zshrc dosyasına eklemeniz yeterlidir:

detach() {
  "$@" 1>/dev/null 2>/dev/null &; disown
}

Ardından, bunun gibi sahipsiz komutları çalıştırabilirsiniz:

detach gedit ~/.zshrc

1

Benim .bashrc, bu işlevler tam olarak bu amaç için var:

function run_disowned() {
    "$@" & disown
}

function dos() {
    # run_disowned and silenced

    run_disowned "$@" 1>/dev/null 2>/dev/null
}

dosTerminalden çıkarılmış olarak çalıştırmak için bir komut ekleyin .

İşlev bashve ile çalışmak üzere yazılmıştır zsh.


1
Bu cevabın neden bir gövdeyi böyle bir bedenle kullanması yeterliyse, bu cevabın neden bir fonksiyonun diğerine sarılmış bir işlevini kullandığı konusunda kafam biraz karıştı ( "$@" & disown) &> /dev/null. Ayrıca kullanmak pek mantıklı 1>ve 2>kullandığınız çünkü disownsen bash kullanıyorsanız anlamına gelir ve bash sadece kolayca yapabilirsiniz &>stdout ve stderr hem yönlendirmek
Sergiy Kolodyazhnyy

İki işlevi var çünkü (1) Bu şekilde okumayı daha kolay buldum, ve (2) run_disownedNokta dosyalarımdaki diğer yerlerde işlevselliğe ihtiyacım var . &>Tabii ki bu konuda haklısın .
mic_e

0

Mac OS X'te, çocuk işleminin terminalden ayrılmadığından emin olmak için hem nohup hem de disown kullanmam gerektiğini öğrendim.


0

Bunu yapmak için aşağıdaki betiği kullanıyorum. nohupKomutun içinde bitmesi durumunda , terminale baskı işlemini durdurur, ayrılır ve geri dönüş durumundan çıkar TIMEOUT.

#!/bin/bash

TIMEOUT=0.1

CMD=( "$@" )
#Could have some shortcuts here, e.g. replace "somefile.c" with "gedit somefile.c"

#use nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send nohup's output to /dev/null, supressing nohup.out
#run nohup in the background so this script doesn't block
#print the command for debugging and to see bash variable expansion
printf "%q " "${CMD[@]}"
echo
nohup "${CMD[@]}" >/dev/null 2>&1 &
NOHUP_PID=$!

#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally

#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $NOHUP_PID
NOHUP_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $NOHUP_STATUS != 0 ] && echo "Error: $CMD"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS

Kullanım örneği:

>>> run false
false
Error: false
>>> echo $?
1
>>> run true
true
>>> run sleep 10
sleep 10
>>>

0

sudo apt install ucommon-utils

pdetach command

İşte gidiyoruz :)


-1

Nohup kullanarak önerilen birçok cevap . Pm2 kullanmanızı öneririm . Kullanılması PM2 üzerinde nohup uygulaması ve çok daha fazla diğer özellikleri için günlük dosyalarını korumak, uygulama hayatta tutmak gibi birçok avantajı vardır. Daha fazla ayrıntı için bunu kontrol edin .

Yüklemek için um2'den indirmek gerekir UÖM'sini . Debian tabanlı sistem için

sudo apt-get install npm

ve Redhat için

sudo yum install npm

Veya bu talimatı takip edebilirsiniz . Kurduktan sonra npm yüklemek için kullanabilirsiniz PM2

npm install pm2@latest -g

Tamamlandıktan sonra başvurunuzu başlatabilirsiniz.

$ pm2 start app.js              # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py              # Start, Daemonize and auto-restart application (Python)

Proses izleme için aşağıdaki komutları kullanın:

$ pm2 list                      # List all processes started with PM2
$ pm2 monit                     # Display memory and cpu usage of each app
$ pm2 show [app-name]           # Show all informations about application

Uygulama adını veya işlem kimliğini kullanarak işlemleri yönetin veya tüm işlemleri birlikte yönetin:

$ pm2 stop     <app_name|id|'all'|json_conf>
$ pm2 restart  <app_name|id|'all'|json_conf>
$ pm2 delete   <app_name|id|'all'|json_conf>

Günlük dosyaları şurada bulunabilir:

$HOME/.pm2/logs #contain all applications logs

1
Unix işlemlerini kontrol etmek için bir NodeJS uygulaması (nohup gibi küçük ve sağlam bir komutun kullanılması) kullanmak gerçekten çok fazla ve dürüst olmak gerekirse oldukça garip görünüyor. Eğer yeniden başlatma fonksiyonelliğine ihtiyacınız olursa, monit'i kullanırdım.
Sergio,

@Sergio, kısıtlı uygulamayı kullanmak sizin tercihiniz.
17:17

Bu yıl birkaç gün önce yayınlandı (bir 4 gün önce), bu nedenle monit'in kullanımdan kaldırılmış bir uygulama olduğunu nasıl / neden düşündüğünü anlamıyorum. @see mmonit.com/monit/changes
Sergio

Nohup hakkında konuşuyordum.
hac,

1
nohupdüz standart bir POSIX komutu, bu yüzden aynı açıklama: itiraz edilemez. @see unix.com/man-page/posix/1p/nohup
Sergio,

-1

Amacınız terminal penceresini çevrede tutmadan bir komut satırı uygulaması başlatmaksa, terminali alt-F2 ile başlattıktan sonra uygulamayı çalıştırmayı deneyebilirsiniz.

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.