Bir komut dosyasından arka plan işlemi başlatma ve komut dosyası sona erdiğinde yönetme


15

Bir komut dosyasındaki bir arka plan programına benzer bir işlemi çalıştırmak ve yapılandırmak istiyorum.
Kabuğum Cygwin altında zsh öykünüyor ve arka plan programı temel bir FTP sunucusu olan SFK .

Burada önemli olan şeyler için senaryo startserv.shaşağıdaki gibi hazırlanabilir:

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
$cmd &

Komut dosyasını çalıştırdıktan sonra startserv.sh, herhangi bir istem göstermeden durur (biter?), Ardından:

  • CTRL+ Chem komut dosyasını hem de arka plan işi işlemini sonlandırır;

  • Vurmak Entersenaryoyu arka planda işlem kalıntıları biter.

Her neyse, sadece üzerinden görebiliyorum psve göremiyorum jobs, bu yüzden, süreci kapatmak kill -9istediğimde, CTRL+ lehine kaçınmak istediğim bir şey olan acımasız bir sinyal göndermeliyim C.

Alternatif olarak tüm betiği arka planda çalıştırabilirsiniz. 'Olur', ancak readkomut dosyası olarak çalıştırılırsa komut kullanıcı girdisini alamaz startserv.sh &.

Geçici bir sunucuya ihtiyacım olduğunu unutmayın, gerçek bir daemon değil : yani, komut dosyası bittikten sonra, basit bir etkileşimli kabuk görevleri (bir sanal makine konukuyla) gerçekleştirmek için sunucu işleminin arka planda çalışmasını istiyorum, ancak ' t Kabuğun hayatta kalması için işleme ihtiyaç yoktur; bu nedenle nohupuygun görünmüyor.


bgproc="$!"ve ardından command "$bgproc" uygun işlemi yapmak için arka planda çalışan işlemin işlem kimliğini alın. Ayrıca bkz stackoverflow.com/questions/1908610/…
Valentin Bajrami

ayrıca bir PID dosyası da oluşturabilirsiniz. Ardından, hangi işlem numarasının olduğunu görmek için o dosyayı okuyun ve oradan gidin.
jgr208

Yanıtlar:


18

Vurmak Entersenaryoyu arka planda işlem kalıntıları biter.

Neredeyse! Aslında, komut dosyası bastığınız zamandan çoktan çıkmıştır Enter. Ancak, isteminizi bu şekilde geri alabilirsiniz (çünkü kabuğunuz $PS1her şeyi tekrar yazdırır ).

İsabet nedeni Ctrl+ Cikisi bağlantılıdır çünkü her ikisi de sonlandırır olduğunu. Komut dosyanızı yürüttüğünüzde, kabuğunuz çalıştırılacağı bir alt kabuk başlatır. Bu alt kabuğu sonlandırdığınızda, arka plan işleminiz muhtemelen bir SIGHUPsinyalden ölür .

Komut dosyasını, arka plan işlemini ve alt kabuğu ayırın

Kullanarak nohup, bu küçük rahatsızlıktan kurtulabilirsiniz.

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &

disownalternatif

'Den' /bin/she geçiş /bin/bashyapabiliyorsanız, denemeyi disownde deneyebilirsiniz . Daha fazla bilgi için help disownbir bashörnek yazın.

disown -h $cmd &

Arka plan sürecini "güzelce" öldürmek

Şimdi, süreç öldürmek söz konusu olduğunda, mükemmel bir " Ctrl+ C" kullanarak yapabilirsiniz kill. Sadece acımasız gönderme SIGKILL. Bunun yerine şunları kullanabilirsiniz:

$ kill -2 [PID]
$ kill -15 [PID]

Bu da işleminize güzel SIGINT(2) veya SIGTERM(15) gönderir . İşleme başladıktan sonra PID değerini de yazdırmak isteyebilirsiniz:

...
nohup $cmd &
echo $!

... hatta daha iyisi, betiğin bir beklemesini sağlayın ve SIGINTarka plan işlemine geri gönderin (bu, betiğinizi ön planda tutar) :

#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &

# Storing the background process' PID.
bg_pid=$!

# Trapping SIGINTs so we can send them back to $bg_pid.
trap "kill -2 $bg_pid" 2

# In the meantime, wait for $bg_pid to end.
wait $bg_pid

A SIGINTyeterli değilse, SIGTERMbunun yerine sadece bir tane kullanın (15):

trap "kill -15 $bg_pid" 2 15

Bu şekilde, komut dosyanız arka plan işlemi için bir SIGINT( Ctrl+ C, kill -2) veya bir SIGTERMsüre alırsa wait, sinyalleri ona aktarır. Bu sinyaller sfkörneği öldürürse, waitçağrı geri döner, bu nedenle komut dosyanızı da sonlandırır :)


1
+1 Çok bilgilendirici. Komut dosyası alt kabukta çalıştığından, komut dosyasından komut dosyasının üst kabuğunun iş tablosuna erişme olasılığı var mı? jobsKomut dosyası bittikten sonra (yerine ps) terminalde verilen liste işleri .
antonio

1
İşler mevcut kabuğunuzla ilişkilendirilir, bir kabuktan diğerine aktarılmazlar. Alt kabuğunuz öldüğünde, işleri kurtarılmaz. Arka plan işleminizin 'PID'sini yazdırarak, alt kabuk sona erdikten sonra bile ( pid -p) hakkında kolayca bilgi edinebilirsiniz .
John WH Smith

güzel bir açıklama, ancak betiğinizde daha fazla komut varsa, hiçbir zaman çalıştırılmazlar (çünkü wait). Beklemeyi kaldırırsanız, sinyal işleme bozulur: /
chefarov
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.