it-swarm-tr.com

Terminal kapanışında hayatta kalacak bir komutu nasıl çalıştırabilirim?

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

redshift

Terminali kapatamıyorum, yoksa işlemi öldürecektir. Bir komutu, işlemi öldürmeden terminali kapatabileceğim şekilde çalıştırabilir miyim?

339
Matthew

Aşağıdakilerden 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ğıdakilere bakın:

342
Steven D

Programınız zaten çalışıyor ise Ctrl-Z İle duraklatabilirsiniz, bg ve ardından disown it ile arka plana çekin:

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

İyi cevap zaten @StevenD tarafından gönderildi, ancak bunun biraz daha açıklığa kavuştuğunu düşünüyorum.

İşlemin terminalin sonlandırılmasıyla öldürülmesinin nedeni, başlattığınız işlemin terminalin bir alt işlemi olmasıdır. Terminali kapattığınızda, bu çocuk süreçleri de öldürecektir. İşlem ağacını pstree ile görebilirsiniz, örneğin kate & Konsole'da:

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

kate işlemini konsole 'dan sonlandırdığınızda konsole' dan ayırmak için, aşağıdaki gibi komutla Nohup kullanın:

Nohup kate &

konsole kapatıldıktan sonra pstree şöyle görünecektir:

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

ve kate hayatta kalacak. :)

Bir alternatif, screen/tmux/byobu kullanmaktır, bu da Kabuğu terminalden bağımsız olarak çalışır durumda tutar.

50
gertvdijk

İşlemi terminalde bu şekilde ç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

31
hanoo

Tüm önerilerin iyi çalışmasına rağmen, alternatifimin ekranınızda sanal bir terminal oluşturan bir program olan screen kullanmak olduğunu gördüm.

screen -S session_name İle başlatmayı düşünebilirsiniz. Ekran neredeyse tüm Linux ve Unix türevlerine kurulabilir. İsabet Ctrl+A ve (küçük harf) C ikinci bir oturum başlatacaktır. Bu, ilk oturumda vurarak ileri ve geri geçiş yapmanıza olanak tanır. Ctrl+A ve  veya yeni oturumu vurarak Ctrl+A ve 1. Bir terminalde on adede kadar oturumunuz olabilir. İş yerinde bir oturum başlatır, eve gider, iş makineme ssh koyar ve sonra screen -d -R session_name Çağırırdım. Bu sizi o uzak oturuma yeniden bağlayacaktır.

10
apolinsky

Tercih ederim:

(uygulama Adı ve)

örneğin: [email protected]:~$ (chromium-browser &)

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

8
daGo

Bir komut dosyası var:

  • Arka planda rastgele komutlar çalıştırma

  • Terminal penceresiyle öldürülmelerini engelleyin

  • Çıktılarını bastır

  • Çıkış durumunu yönetir

Özellikle gedit, evince, inkscape vb. Komut TIMEOUT öncesinde biterse, sıfır yerine Nohup'un çıkış durumu 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
7
jozxyqk

Tüm bunları yapmanın yalnızca Shell yöntemi, stdin'i kapatıp komutu arka plan yapmaktır:

command <&- & 

O zaman Shell'den çıktığınızda bırakılmaz. Stdout'u yeniden yönlendirmek isteğe bağlı bir şeydir.

Dezavantajı, bundan sonra bunu yapamazsınız.

7
w00t

Oturumu kapatıp terminal oturumunu kapattıktan sonra HUP sinyali almayacak bir işlem (PID) ayarlayabilirsiniz. Aşağıdaki komutu kullanın:

Nohup -p PID
4
tony

Muhtemelen apolinsky tarafından sunulan cevap benzer, screen bir varyant kullanın. Vanilya komutu böyle

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

Oturumun bağlantısı kesilebilir Ctrl ACtrl D ve basit bir durumda screen -r. Ben rahat erişim için hazır benim session yaşayan PATH adlı bir komut dosyası sarılmış var:

#!/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 "[email protected]; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'"
    echo "ERROR: 'screen' is not installed on this system" >&2
fi
exit 1

Bu yalnızca önceden bir programın bağlantısını kesmek istediğinizi biliyorsanız çalışır. Halihazırda çalışmakta olan bir programın bağlantısının kesilmesini sağlamaz.

3
roaima

Daha önce gönderilen diğer cevaplara benzer şekilde, reptyr sayesinde çalışmakta olan bir işlemi “ekran” ı geriye dönük olarak aktarmak ve sonra terminali kapatmak mümkündür. Adımlar bu post bölümünde açıklanmıştır. Atılacak adımlar şunlardır:

  1. Süreci askıya alma
  2. İşlemi arka planda devam ettir
  3. Süreci reddetme
  4. Ekran oturumu başlatma
  5. Sürecin PID'sini bulun
  6. Süreci devralmak için reptyr kullanın
2
user308879