Terminali kapatacak bir komutu nasıl çalıştırabilirim?


313

Bazen bir süreç başlatmak ve unutmak istiyorum. Komut satırından başlatırsam, şöyle:

redshift

Terminali kapatamıyorum, yoksa işlemi öldürecek. Komutu, işlemi öldürmeden terminali kapatabilecek şekilde çalıştırabilir miyim?


4
Değil varsayılan tüm dağıtımlarda yüklemek, ancak ekranı arkadaşıdır: en.wikipedia.org/wiki/GNU_Screen
Zayne S Halsall

Aynı sorunla karşılaşan herkes için: Unutmayın, siz yazsanız yourExecutable &ve çıkışlar ekrana gelmeye devam Ctrl+Cetse ve hiçbir şeyi durdurmuyor gibi görünse bile , sadece kör bir şekilde yazın disown;ve Enterekran çıktılarla kaydırılıyor olsa bile tuşuna basın. sen yazıyorsun İşlem reddedilecek ve işlemi ölmeden terminali kapatabileceksiniz.
Nav

Böyle tmux gibi ekran çoklayıcı kullanabilirsiniz . Ubuntu makinelerinde apt-get üzerinden kullanılabilir
Himanshu

Yanıtlar:


311

Aşağıdaki 2’den biri çalışmalıdır:

$ nohup redshift &

veya

$ redshift &
$ disown

Bunun nasıl çalıştığı hakkında biraz daha fazla bilgi için aşağıya bakın:


5
İkincisi ( redshift & disown) Ubuntu 10.10'da benim için çalıştı. Her şeyi tek bir satıra koymak iyi çalışıyor gibi görünüyor. Bunu yapmamam için herhangi bir neden var mı?
Matthew

4
@Matthew Birincisi de iyi çalışması gerekir, sadece ikincisi gibi arka plan yapmaz (muhtemelen arka plan yapmasını istersiniz nohup redshift &). Ve ikinciyi bir satıra koymak gayet iyi, ancak genelde ;( redshift &; disown) ile
ayrılmanıza

10
@Michael: Her ikisi de ;ve &komut ayırıcılar ve eşit önceliğe sahip. Tek fark, senkronize ve senkronize olmayan uygulamalardır (sırasıyla). &;Sadece tercih etmek için kullanmaya gerek yoktur &(çalışır, ancak biraz gereksizdir).
Chris Johnsen

4
iyi bir cevap, stdout ve stderr'i yeniden yönlendirmenin iyi bir fikir olacağını ekleyebiliriz, böylece terminal hata ayıklama çıktısı ile spam göndermeyecek
Kim

12
Ayrıca, redshift &!derhal kırmızıya kayma sona erer.

143

Programınız zaten çalışıyorsa , duraklatabilirsiniz Ctrl-Z, arkaplana bgve sonra disownda arkasına doğru çekin :

$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
$ bg
$ disown
$ exit

3
Görevden alındıktan sonra çalışan sürecin stdout'unu nasıl tekrar okuyabilirim?
Necktwi


1
Bu benim için nedense işe yaramadı (centos)
Ian

Bu işlemden sonra süreci nasıl öldürürsünüz?
Palak Darji

2
@necktwi disownstdout veya stderr bağlantısını kesmiyor . Ancak nohup, >/dev/null(standart bağlantıyı kesme) olduğu gibi 2>/dev/null(standart hata bağlantısını kesme) yapar. ( disown) İş kontrolünün bağlantısını keser.
ctrl-alt-delor,

45

İyi bir cevap zaten @StevenD tarafından gönderildi, ancak bunun biraz daha netleşebileceğini düşünüyorum.

İşlemin terminalin sona ermesiyle öldürülmesinin nedeni, başlattığınız işlemin terminalin bir alt işlemi olmasıdır. Terminali kapattığınızda, bu çocuk işlemlerini de öldürür. İşlem ağacını pstreeörneğin kate &Konsole'de çalışırken görebilirsiniz :

init-+
     ├─konsole─┬─bash─┬─kate───2*[{kate}]
     │         │      └─pstree
     │         └─2*[{konsole}]

Yapmak için kateayrılmış işlemi konsolesonlandırmak zaman konsole, kullanmak nohupböyle komutuyla:

nohup kate &

Kapanışından sonra konsole, pstreebu gibi görünecektir:

init-+
     |-kate---2*[{kate}]

ve katehayatta kalacak. :)

Bir alternatif de terminalden bağımsız olarak kabuğun çalışmasını sağlayacak screen/ tmux/ kullanımıdır byobu.


Uzaklaştırma yöntemleriyle ilgili problemlerim vardı. Bu şu anda benim için çalışıyor, bu yüzden olumlu. Ben de tail-f nohup.out can çünkü böyle oluyor whats gördüm ancak oturum başarısız dert değil
Ian

27

Terminalde böyle bir işlemi çalıştırabilirsiniz

setsid process

Bu, programı yeni bir oturumda çalıştıracaktır. Açıklandığı gibi http://hanoo.org/index.php?article=run-program-in-new-session-linux


1
Setsid'in nohup'a göre avantajları olarak ne görüyorsunuz?
Ekim'de

1
1) Hakkında sinir bozucu bir mesaj yazdırmaz nohup.out. 2) Kabuğunuzun iş listesinde kalmaz, bu yüzden çıktısını karıştırmaz jobs.
Mikel

Lxterminal'de çalışan script ile çalışan tek çözüm budur, pcmanfm'i başlatır ve çıkar (pcmanfm çalışmaya devam ederken terminalin kapanabileceği setsid ile). Çok teşekkür ederim!
desgua

9

Tüm önerilerin iyi sonuç vermesine rağmen, alternatifim kullanmak için buldum screen, ekranınızda sanal bir terminal kuran bir program.

Başlayarak düşünebilirsiniz . Ekran hemen hemen tüm Linux ve Unix türevlerine kurulabilir. Vurmak + ve (küçük harf) , ikinci oturumu başlayacak. Bu vurarak ileri geri ilk oturumu arasında geçiş yapmak için izin verecek + ve vurarak ya da daha yeni bir oturum + ve . Bir terminalde en fazla on oturum olabilir. İşyerinde bir oturuma başlardım, eve giderim, iş makineme girer ve sonra çağırırdım . Bu sizi o uzak oturuma yeniden bağlar.screen -S session_nameCtrlACCtrlA0CtrlA1screen -d -R session_name


screen -d -m commandZaten ayrılmış ekranda başlayacak: ~# screen -d -m top ~# screen -ls There is a screen on: 10803..Server-station (Detached) 1 Socket in /root/.screen. ~# screen -x .... ve sen.
Dr. Alexander

7

Bütün bunları yapmanın tek yolu stdin'i kapatmak ve komutu geri planlamaktır:

command <&- & 

Öyleyse kabuktan çıktığınızda pes etmez. Stdout yönlendirmek yapmak için güzel bir isteğe bağlı bir şeydir.

Dezavantajı ise bundan sonra yapamayacağınız şey.


Ubuntu'da denedim. Öldürme terminali de başlatılan süreci kapattı. Bunun neden olabileceği hakkında bir fikrin var mı?
Ashok Koyi

7

Bir komut dosyası var:

  • İsteğe bağlı komutları arka planda çalıştır

  • Terminal penceresiyle öldürülmelerini önle

  • Çıktılarını bastırmak

  • Çıkış durumunu işler

Ben esas olarak kullanmak gedit, evince, inkscapetüm can sıkıcı terminali çıkışının çok var olduğunu vb. Komut daha önce TIMEOUTbiterse, nohup'un çıkış durumu sıfır yerine döndürülür.

#!/bin/bash

TIMEOUT=0.1

#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
nohup "${@}" >/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 ${@}"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS

örnekler ...

>>> run true && echo success || echo fail
success
>>> run false && echo success || echo fail
Error false
fail
>>> run sleep 1000 && echo success || echo fail
success
>>> run notfound && echo success || echo fail
Error notfound
fail

6

Tercih ederim:

(Uygulama Adı &)

Örneğin: linux@linux-desktop:~$ (chromium-browser &)

Komutu yazarken parantez kullandığınızdan emin olun!


1
Terminalin kapatılması, OP'nin (ve ben, bu nedenle buraya gelenlerin) kaçınmak istedikleri tam olarak ne olmasını istiyorsa , süreci öldürecektir
gromit190

Muhtemelen cevabımda parantez olmadan kullandığım bir emir komutuna sahipsiniz, eğer öyleyse terminali kapatmak işlemi öldürür, aksi takdirde gerçekleşmez. Bunu netleştirmek için yukarıdaki çözümü zaten düzenledim.
daGo

benim için çalış, tnx
noadev 14:18

Bunun neden daha fazla yükseltme olmadığını merak ediyorum. nohupherhangi bir tty çıktısını önler ve aslında çıktıyı bir dosyaya yönlendirmek istedim ve bu da benim için daha iyi bir çözüm olmasını önledi.
redanimalwar

4

Çıkış yapıp terminal oturumunu kapattıktan sonra HUP sinyali alamayacak bir işlem (PID) ayarlayabilirsiniz. Aşağıdaki komutu kullanın:

nohup -p PID

3

Muhtemelen apolinsky tarafından sunulan cevaba benzer , üzerinde bir değişken kullanıyorum screen. Vanilya emri böyle.

screen bash -c 'long_running_command_here; echo; read -p "ALL DONE:"'

Ctrl ACtrl DBasit bir durumda oturumun bağlantısı kesilebilir ve yeniden bağlanabilir screen -r. Bunu rahatça erişime hazır olduğumda sessionyaşayan bir senaryoya sardım.PATH

#!/bin/bash
#
if screen -ls | awk '$1 ~ /^[1-9][0-9]*\.'"$1"'/' >/dev/null
then
    echo "WARNING: session is already running (reattach with 'screen -r $1')" >&2
else
    exec screen -S "$1" bash -c "$@; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'"
    echo "ERROR: 'screen' is not installed on this system" >&2
fi
exit 1

Bu sadece bir programın bağlantısını kesmek istediğinizi önceden bildiğinizde çalışır. Çalışmakta olan bir programın bağlantısının kesilmesini sağlamaz .


2

Daha önce gönderilen diğer cevaplara benzer şekilde, çalışan bir işlemi, reptyr sayesinde geriye dönük olarak "ekran" kullanmak için aktarabilir ve ardından terminali kapatabilirsiniz. Bu yazıdaki adımlar açıklanmıştır . Atılacak adımlar:

  1. Süreci askıya al
  2. İşlemi arka planda devam ettir
  3. İşlemi reddetmek
  4. Bir ekran oturumu başlatmak
  5. İşlemin PID'sini bulun
  6. Süreci ele geçirmek için reptyr kullanın
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.