2012-02-24 21 views
6

मेरे पास एक वेब सर्वर है जहां मैं कुछ धीमे-प्रारंभिक प्रोग्राम डेमन्स के रूप में चलाता हूं। इन्हें कभी-कभी त्वरित पुनरारंभ करने (या रोकना) की आवश्यकता होती है जब मैं उन्हें पुन: संकलित करता हूं या उनकी दूसरी स्थापना में स्विच करता हूं।अन्य उपयोगकर्ताओं को सरल बैश डिमन्स को रोकने/पुनरारंभ करने दें - सिग्नल का उपयोग करें या क्या?

http://mywiki.wooledge.org/ProcessManagement से प्रेरित होकर, मैं एक स्क्रिप्ट daemonise.sh बुलाया

#!/bin/sh 
while :; do 
    ./myprogram lotsadata.xml 
    echo "Restarting server..." 1>&2 
done 

एक चल "डेमॉन" रखने के लिए की तरह लग रहा है कि लिख रहा हूँ। तब शायद

$ ./daemonise.sh & DPID=$! 
$ screen -d 

मैं MyProgram पुनः संकलित करें, एक नया पथ के लिए इसे स्थापित, शुरू नया एक: जब से मैं कभी कभी इसे रोकने के लिए, या बस यह पुनः आरंभ करने की जरूरत है, मुझे लगता है कि स्क्रिप्ट एक स्क्रीन सत्र में चलाने के लिए, की तरह अप और पुराने वाले को मारने के लिए चाहता हूँ:

$ screen -r 
$ kill $DPID 
$ screen -d 

यह ठीक काम करता है जब मैं केवल मेंटेनर हूँ, लेकिन अब मैं किसी और बंद/कार्यक्रम को पुनः आरंभ, कोई फर्क नहीं पड़ता है जो इसे शुरू कर दिया बताना चाहते हैं। और चीजों को और अधिक जटिल बनाने के लिए, daemonise.sh स्क्रिप्ट वास्तव में लगभग 16 प्रोग्राम शुरू करता है, जिससे आप अपने पीआईडी ​​को नहीं जानते हैं, तो हर एक को को मारने में परेशानी होती है।

किसी अन्य उपयोगकर्ता को देने का "सर्वोत्तम अभ्यास" तरीका क्या होगा डिमन्स को रोक/पुनरारंभ करें?

मैंने साझा स्क्रीन सत्रों के बारे में सोचा, लेकिन यह सिर्फ हैकी और असुरक्षित लगता है। सबसे अच्छा समाधान मैं अब के लिए लेकर आए हैं शुरू करने और एक स्क्रिप्ट है कि कुछ संकेत पकड़ता में मौत हो गई रैप करने के लिए है:

#!/bin/bash 
DPID= 
trap './daemonise.sh & DPID=$!' USR1 
trap 'kill $DPID' USR2 EXIT 

# Ensure trapper wrapper doesn't exit: 
while :; do 
    sleep 10000 & wait $! 
done 

अब, किसी अन्य उपयोगकर्ता डेमॉन को रोकने के लिए की आवश्यकता चाहिए और मैं यह नहीं कर सकते , उसे सिर्फ रैपर के ढक्कन को जानना है, और उदाहरण के लिए sudo kill -s USR2 $wrapperpid। (इसके अलावा, यह रीबूट पर डेमन्स चलाने के लिए संभव बनाता है, और फिर भी उन्हें साफ से मारता है।)

क्या कोई बेहतर समाधान है? क्या इस समाधान के साथ स्पष्ट समस्याएं हैं जिन्हें मैं नहीं देख रहा हूं?

+1

+1 ग्रेग के बैश विकी को जोड़ने के लिए +1। सौभाग्य! – shellter

+1

पिड फ़ाइलें सबसे अच्छा सम्मेलन – reconbot

+0

@ जादूगर सही है। आपको एक सार्थक उत्तर नहीं मिलेगा क्योंकि आप मूल रूप से कह रहे हैं "मुझे पता है कि पहिया मौजूद है, लेकिन मैं अपना खुद का आविष्कार करना चाहता हूं"। –

उत्तर

1

मैं एक पीआईडी ​​आधारित init स्क्रिप्ट की सिफारिश (पढ़ने ग्रेग के बैश विकी के बाद, मैं pgrep या पीआईडी-फ़ाइलें ... शामिल किसी भी समाधान से बचना चाहते हैं)। स्क्रिप्ट के लिए विशेषाधिकार प्राप्त कोई भी व्यक्ति सर्वर प्रक्रियाओं को शुरू और बंद करने में सक्षम होगा।

+1

"पीआईडी ​​आधारित"? आपका मतलब पीआईडी-फाइल आधारित है? यदि मैं अन्य उपयोगकर्ताओं को सर्वर पर एक बार में 16 प्रक्रियाओं को रोकने की अनुमति देता हूं, तो मैं पीआईडी ​​को गलत प्रक्रियाओं को इंगित करने का जोखिम नहीं लेना चाहता हूं। आप कैसे सुनिश्चित करेंगे कि प्रक्रियाओं में से कोई भी बंद नहीं हुआ है और अपने पीआईडी ​​को अन्य प्रक्रियाओं में माता-पिता से नियंत्रित किए बिना दिया गया है? – unhammer

+1

अपने प्रोग्राम अपनी खुद की पिड फ़ाइलों को बनाने और साफ़ करने दें। संभावना है कि एक प्रोग्राम दुर्घटनाग्रस्त हो जाएगा और इसकी पीआईडी ​​को दूसरी प्रक्रिया में दिया जाना काफी कम है (इसे सभी उपलब्ध पिड्स आमतौर पर 64 बिट int के आसपास लपेटना होगा)। यदि आप अभी भी चिंतित हैं तो इसे देखें कि प्रक्रियाओं को मारने से पहले क्या प्रक्रिया है। (/ proc/pID/cmdline एक आसान तरीका है।) – reconbot

+1

@ विज़ार्ड: यह कौन सा मंच था? मैं 64-बिट उबंटू 11.10 चला रहा हूं, और/proc/sys/kernel/pid_max '32768' कहता है। यह * नहीं * लपेटने के लिए एक लंबा समय लगता है। – l0b0

1

अपने दृष्टिकोण में सुधार करने के लिए: यह सुनिश्चित करने के लिए सलाह नहीं दी जाएगी कि sleep 10000 & wait $! में कमांड ठीक से समाप्त हो जाता है यदि आपकी पिडवापर स्क्रिप्ट किसी भी तरह से निकलती है?

अन्यथा कुछ समय के लिए प्रक्रिया तालिका में एक खतरनाक sleep प्रक्रिया बनी रहेगी।

इसी तरह, नहीं यह ठीक से पुनः आरंभ करने पर daemonise.sh में myprogram समाप्त करने के लिए क्लीनर होगा (i। ई। यदि daemonise.sh एक TERM संकेत प्राप्त)?

इसके अलावा, नौकरी अधिसूचना संदेशों को दबाने और मारने से पहले पिड अस्तित्व के परीक्षण के लिए संभव है।

#!/bin/sh 
# cat daemonise.sh 

# cf. "How to suppress Terminated message after killing in bash?", 
# http://stackoverflow.com/q/81520 

trap ' 
    echo "server shut down..." 1>&2 
    kill $spid1 $spid2 $spid3 && 
     wait $spid1 $spid2 $spid3 2>/dev/null 
    exit 
' TERM 

while :; do 
    echo "Starting server..." 1>&2 
    #./myprogram lotsadata.xml 
    sleep 100 & 
    spid1=${!} 
    sleep 100 & 
    spid2=${!} 
    sleep 100 & 
    spid3=${!} 
    wait 
    echo "Restarting server..." 1>&2 
done 

#------------------------------------------------------------ 

#!/bin/bash 
# cat pidwrapper 

DPID= 

trap ' 
    kill -0 ${!} 2>/dev/null && kill ${!} && wait ${!} 2>/dev/null 
    ./daemonise.sh & DPID=${!} 
' USR1 

trap ' 
    kill -0 ${!} 2>/dev/null && kill ${!} && wait ${!} 2>/dev/null 
    kill -0 $DPID 2>/dev/null && kill $DPID && wait ${DPID} 2>/dev/null 
' USR2 

trap ' 
    trap - EXIT 
    kill -0 $DPID 2>/dev/null && kill $DPID && wait ${DPID} 2>/dev/null 
    kill -0 ${!} 2>/dev/null && kill ${!} && wait ${!} 2>/dev/null 
    exit 0 
' EXIT 

# Ensure trapper wrapper does not exit: 
while :; do 
    sleep 10000 & wait $! 
done 

#------------------------------------------------------------ 

# test 

{ 
wrapperpid="`exec sh -c './pidwrapper & echo ${!}' | head -1`" 
echo "wrapperpid: $wrapperpid" 
for n in 1 2 3 4 5; do 
    sleep 2 
    # start daemonise.sh 
    kill -s USR1 $wrapperpid 
    sleep 2 
    # kill daemonise.sh 
    kill -s USR2 $wrapperpid 
done 
sleep 2 
echo kill $wrapperpid 
kill $wrapperpid 
} 
+0

हाँ ... मैं वास्तव में यह देखना पसंद करता हूं कि क्या समाप्त कर दिया गया है :-) लेकिन हाँ जो काम करता है। रैपर से भटक नींद की प्रक्रिया के बारे में सोचा नहीं था। – unhammer