मैं स्टार्ट-स्टॉप-डेमॉन द्वारा शुरू की गई प्रक्रिया के स्टडआउट को कैसे लॉग कर सकता हूं?


120

मैं एक सरल प्रक्रिया को चलाने के लिए एक init स्क्रिप्ट का उपयोग कर रहा हूं, जिसे इसके साथ शुरू किया गया है:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS

$ DAEMON नामक प्रक्रिया आमतौर पर अपने मानक आउटपुट में लॉग जानकारी प्रिंट करती है। जहां तक ​​मैं बता सकता हूं कि यह डेटा कहीं संग्रहीत नहीं किया जा रहा है।

मैं $ DAEMON के stdout को किसी फ़ाइल में लिखना या जोड़ना चाहूंगा।

एकमात्र उपाय जो मुझे पता है कि सीधे $ डेमोन के बजाय एक गोले को कॉल करने के लिए स्टार्ट-स्टॉप-डेमॉन को बताना है; स्क्रिप्ट तब $ DAEMON को कॉल करती है और लॉगफाइल को लिखती है। लेकिन इसके लिए एक अतिरिक्त स्क्रिप्ट की आवश्यकता होती है, जैसे कि डेमन को संशोधित करना, इस तरह के सामान्य कार्य को हल करने का गलत तरीका लगता है।

जवाबों:


127

Ypocat के उत्तर पर विस्तार करने के लिए, क्योंकि यह मुझे टिप्पणी नहीं करने देगा:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
 --make-pidfile --pidfile $PIDFILE --background       \
 --startas /bin/bash -- -c "exec $DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

execडेमॉन चलाने के लिए उपयोग करने से केवल बैश माता-पिता के बजाय बच्चे की प्रक्रिया को सही ढंग से रोकने की अनुमति मिलती है।

--startasइसके बजाय का उपयोग --execयह सुनिश्चित करता है कि प्रक्रिया को सही तरीके से इसकी पिड द्वारा पता लगाया जाएगा और अगर गलती से कई बार शुरू किया जाता है तो डेमॉन के कई उदाहरणों को शुरू नहीं करेगा। अन्यथा, स्टार्ट-स्टॉप-डेमॉन एक / बिन / बैश प्रक्रिया की तलाश करेगा और डेमॉन चलाने वाली वास्तविक बाल प्रक्रिया को अनदेखा करेगा।


2
यह @ypocat में से एक मुख्य कारण डेमॉन नीचे फिर से बदल कर बंद की तुलना में कहीं बेहतर समाधान है --startके साथ --stopवास्तव में काम करता है।
— 15'14

मैंने init.d के बजाय rc.local से इस कमांड को चलाने की कोशिश की ... मुझे लगता है कि वही परिणाम नहीं मिल रहे हैं। हालाँकि जब इसे SSH के माध्यम से शेल से चलाया जाता है तो यह एक आकर्षण की तरह काम करता है!
— नेमो

1
साथ कैसा लगेगा start-stop-daemon --test (...)?
— अब्दुल

2
@MattClimbs यह हर शुरुआत के बाद फाइल को ओवरराइट करता है। का उपयोग >>करने के बजाय >संलग्न करने के लिए।
— मेव

2
इससे पहले कि आप बाहर (मेरी तरह) फ्रीक करें क्योंकि आपका लॉग खाली था, ध्यान रखें कि यह बफर है! आप "निष्पादित stdbuf -oL -eL $ DAEMON $ DAEMONARGS> $ LOGFILE 2> और 1" का उपयोग कर प्रत्येक लाइन को फ्लश करने के लिए मजबूर कर सकते हैं ( blog.lanyonm.org/articles/2015/11/11/… ) से
— piers7

47

आपको करने की जरूरत है:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec /bin/bash -- -c "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

यदि आप उपयोग करते हैं --chuidया करते हैं --user, तो सुनिश्चित करें कि उपयोगकर्ता लिख /var/logया मौजूदा कर सकता है /var/log/some.log। सबसे अच्छा तरीका है कि उस उपयोगकर्ता के पास /var/log/subdir/हालांकि है।


1
शानदार, धन्यवाद ypocat। आज, लॉग को सहेजने के साथ-साथ, मुझे एक गैर-बाइनरी स्क्रिप्ट चलाने की आवश्यकता थी जो --exec अनुमति नहीं देता है लेकिन आपकी चाल काम करती है!
— joeytwiddle

8
नीचे की ओर ... सेवा रोकना मार मारता है, लेकिन बच्चे की प्रक्रिया शुरू नहीं हुई है! (मेरे मामले में, डेमोन = कॉफी)।
— joeytwiddle

1
मैंने do_stop के शीर्ष पर bash प्रक्रिया की सभी बाल प्रक्रियाओं को मारकर चारों ओर काम किया। bashPID=$(cat $PIDFILE); [ -n "$bashPID" ] && pkill -P "$bashPID"
— joeytwiddle

5
जानकर अच्छा लगा, और pkillसमाधान भी। सोच रहा था कि क्या होगा ... -c "exec $DAEMON..."("निष्पादन" को जोड़ते हुए)। प्लेट पर अभी यह मत करो तो यह कोशिश नहीं कर सकता।
— youurayy

12
@ypocat मैंने अभी सत्यापित किया है कि यह -c के साथ काम करता है "निष्पादित $ डेमन ..."। इसका मतलब है कि pkill हैक्स की आवश्यकता नहीं है।
— overthink

40

ऐसा लगता है कि आपको डेमॉन आउटपुट पर कब्जा --no-closeकरने के start-stop-daemonलिए शुरू करते समय अब पैरामीटर का उपयोग करने में सक्षम होना चाहिए । यह नई सुविधाdpkg पैकेज में डेबियन पर संस्करण 1.16.5 के बाद से उपलब्ध है :

नए - आन-क्लोज ऑप्शन को जोड़ें - बैकग्राउंड पर क्लोजिंग फड्स डिसेबल करने के लिए।

इसने कॉल करने वाले को डिबगिंग उद्देश्यों के लिए प्रक्रिया संदेश देखने में सक्षम किया, या फाइल, सिसलॉग या समान लॉग इन करने के लिए फ़ाइल विवरणकर्ताओं को पुनर्निर्देशित करने में सक्षम किया।


8
यह शर्म की बात है कि यह उबंटू 12.04 :( में उपलब्ध नहीं है।
— लियोन राडली

मुझे लगता है कि काम करने के लिए बंद नहीं मिल सकता है ... उत्पादन अभी भी खोल रहा है कि मैं से init.d स्क्रिप्ट निष्पादित कर रहा हूँ :(
— stantonk

+1 डेबियन पर पूरी तरह से एक डेमॉनेटाइज़्ड नोड.जेएस सेवा के साथ काम करता है।
— 12

2
@stantonk क्या आपने फ़ाइल में stdout / stderr को भी पाइप किया? पूरा कमांड लाइन निम्न प्रकार दिखता है। और सुनिश्चित करें कि लॉगफ़ाइल को $ USER द्वारा लिखा जा सकता है: start-stop-daemon --start --chuid $ USER --pidfile $ PIDFILE --background --no-close --make-pidfile --exec $ DAEMON - $ DAEMONARGS >> /var/log/xxxxx.log 2> & 1
— nharrer

1
यह ओपन आर्क के साथ उपलब्ध नहीं है start-stop-daemon। हालाँकि ओपनस्कैप संस्करण में क्रमशः स्टडआउट और स्टडर को पुनर्निर्देशित करने के विकल्प -1और -2विकल्प हैं।
— थोड़ा-बहुत दोस्त

14

Openrc के साथ (जो उदाहरण के लिए जेंटू या अल्पाइन लाइनक्स पर डिफ़ॉल्ट है) start-stop-daemonमें विकल्प -1और -2विकल्प हैं:

-1, --stdout फ़ाइल पर रीडायरेक्ट स्टडआउट करें

-2, -स्टैंडर रीडायरेक्टर को फाइल करने के लिए पुनर्निर्देशित करें

तो आप बस लिख सकते हैं:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE

9

डेमॉन के आउटपुट को कैप्चर करना और उसे फ़ाइल में सहेजना बहुत मुश्किल नहीं है:

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas $DAEMON --no-close \
  -- $DAEMON_ARGS >> $LOGFILE 2>&1

हालाँकि यह समाधान के लिए उप-योग हो सकता है logrotate।

यह बेहतर हो सकता है कि आउटपुट को syslog पर कब्जा कर लिया जाए। पर डेबियन इस systemd सेवाओं के व्यवहार से मेल खाएगा। उपरोक्त उदाहरण को फिर से लिखने का निम्नलिखित सीधा प्रयास गलत है क्योंकि यह दो माता-पिता ("ज़ोंबी") प्रक्रियाओं (लकड़हारा और डेमन) को पीछे छोड़ देता है क्योंकि डेमन को रोकना क्योंकि start-stop-daemonकेवल उसके बच्चे को समाप्त करता है, लेकिन सभी वंशज नहीं हैं:

## Do not use this!
start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /bin/sh \
  -- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME"""

इसे काम करने के लिए हमें एक रैपर की आवश्यकता होती है जो अपने बच्चों को प्राप्त करने SIGTERMसे समाप्त कर देता है start-stop-daemon। कुछ हैं:

दोहे :
start-stop-daemon --start --background \
  --pidfile $PIDFILE \
  --startas /usr/sbin/duende \
  -- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME \
  /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS"""

नोट: uid=65534एक उपयोगकर्ता है nobody।

पेशेवरों : यह काम करता है और यह अपेक्षाकृत आसान है।
विपक्ष : 4 प्रक्रियाएं (पर्यवेक्षक duende, गिरा हुआ विशेषाधिकार (लकड़हारा), suऔर डेमन के साथ इसका कांटा ); अनिवार्य --chroot; यदि डेमन तुरंत समाप्त हो जाता है (जैसे अमान्य आदेश)status_of_proc -p $PIDFILE "$DAEMON" "$NAME" इसे सफलतापूर्वक शुरू कर दिया गया है।

डेमॉन :
start-stop-daemon --start --pidfile $PIDFILE \
  --startas /usr/bin/daemon \
  -- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info \
  -- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS"""

पेशेवरों : 3 प्रक्रियाएं (पर्यवेक्षक daemon, suऔर स्वयं डेमन)।
विपक्ष : डेमन के कमांड लाइन विकल्पों $PIDFILEको भ्रमित करने के कारण प्रबंधन करना मुश्किल ; यदि डेमन तुरंत समाप्त हो जाता है (जैसे अमान्य आदेश)status_of_proc -p $PIDFILE "$DAEMON" "$NAME" इसे सफलतापूर्वक शुरू कर दिया गया है।

पाइपेक्सेक ( विजेता ):

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /usr/bin/pipexec -- -k \
   -- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] '{D:2>D:1}' '{D:1>L:0}'

पेशेवरों : 3 प्रक्रियाएं (पर्यवेक्षक pipexec, loggerऔर डेमन खुद); यदि डेमन तुरंत समाप्त हो जाता है (जैसे अमान्य आदेश) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"सही ढंग से विफलता की रिपोर्ट करता है।
विपक्ष : कोई नहीं।

यह विजेता है - सबसे आसान, साफ समाधान जो अच्छी तरह से काम करता है।


7

आमतौर पर start-stop-daemonपृष्ठभूमि में चलने के दौरान मानक फ़ाइल डिस्क्रिप्टर बंद हो जाता है। के मैन पेज से start-stop-daemon:

-C, --no-close
बैकग्राउंड में डेमन को मजबूर करते समय किसी भी फाइल डिस्क्रिप्टर को बंद न करें। डिबगिंग उद्देश्यों के लिए उपयोग किया जाता है प्रक्रिया आउटपुट, या प्रक्रिया आउटपुट लॉग करने के लिए फ़ाइल डिस्क्रिप्टर को रीडायरेक्ट करने के लिए। केवल प्रासंगिक है - उपयोग करते समय - बैकग्राउंड।

यह एक मेरे लिए काम किया:

    start-stop-daemon -b -C -o -c \ 
         $DAEMON_USER -S -x $DAEMON > $DAEMON_LOG 2>&1

4

एक पुरानी मेलिंग सूची का हवाला देते हुए:

https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html

एक आसान - और यदि आप स्टार्ट-स्टॉप-डेमॉन का उपयोग करना चाहते हैं, तो संभव है कि इसके चारों ओर एक छोटी स्क्रिप्ट बनाई जाए:

#!/bin/sh
exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log

और फिर उस स्क्रिप्ट को स्टार्ट-स्टॉप-डेमॉन के तर्क के रूप में उपयोग करें।

हालांकि असली सवाल यह है कि क्या पहली जगह में स्टार्ट-स्टॉप-डेमन का उपयोग करना वास्तव में आवश्यक है?


3

मुझे यकीन नहीं है कि अगर "$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2> & 1" कभी लॉग फाइल के लिए फाइल डिस्क्रिप्टर को बंद कर देगा ... जिसका मतलब है कि यदि आपका डेमॉन हमेशा के लिए चलता है, तो मुझे यकीन नहीं है। डिस्क स्थान को साफ करने के लिए लॉगरोट या अन्य तंत्र काम करेंगे। चूंकि यह> के बजाय> है, इसलिए सुझाए गए कमांड रीस्टार्ट पर मौजूदा लॉग को भी अलग कर देगा। यदि आप यह देखना चाहते हैं कि डेमन दुर्घटनाग्रस्त क्यों हुआ, और यह अपने आप पुनः आरंभ हो जाता है, तो यह बहुत उपयोगी नहीं हो सकता है।

एक अन्य विकल्प "$ DAEMON | लकड़हारा" हो सकता है। लकड़हारा एक कमांड है जो syslog (/ var / log / संदेश) में प्रवेश करेगा। यदि आपको stderr की आवश्यकता है, तो मुझे लगता है कि आप "$ DAEMON 1> & 2 | लकड़हारा" का उपयोग कर सकते हैं।


आप सही हैं, का उपयोग >>करना आमतौर पर डेमॉन के लिए अधिक उपयुक्त है, हालांकि इसका मतलब है कि आपको अब एक लॉरोगेट नियम बनाना चाहिए!
— joeytwiddle

डिस्क-स्पेस के लिए, जो विधियाँ फ़ाइल को काटती हैं, उन्हें तुरंत वापस स्पेस मिलेगा (कम से कम एक्सट्रीम फाइल सिस्टम के तहत)। लेकिन खबरदार तरीके जो बस एक फ़ाइल को हटाते हैं जो अभी भी लिखा जा रहा है: संभाल जारी होने तक अंतरिक्ष को पुनः प्राप्त नहीं किया जाएगा, और आप फ़ाइल नोड को मैन्युअल रूप से इसे छोटा करने के लिए नहीं ढूंढ सकते हैं!
— joeytwiddle

यहाँ मेरी बात का @joeytwiddle हिस्सा यह है कि अगर फ़ाइल हैंडल कभी बंद न हो तो लॉगरोटेट लॉग को घुमाने में विफल हो जाएगा।
— nairbv

--no-close ... | loggerमेरे लिए काम नहीं करता है (डेबियन 7.3, स्टार्ट-स्टॉप-डेमन 1.16.12)। स्टार्ट-स्टॉप-डेमॉन स्क्रिप्ट वापस नहीं आती है, हालांकि / var / log / संदेश भरा हुआ है :-)। मैंने इसके साथ और बिना कोशिश की 1>&2।
— hgoebl

hgoebl आपको उद्धरणों में "cmd | लकड़हारा" अभिव्यक्ति की आवश्यकता है, इसलिए दुभाषिया को पता चल जाएगा कि यह "cmd" है आप लकड़हारे को पाइप कर रहे हैं, न कि स्टार्ट-स्टॉप-डेमन अभिव्यक्ति।
— Wexxor

2

मान लें कि यह बैश है (हालांकि कुछ अन्य गोले इसे भी अनुमति दे सकते हैं), पंक्ति:

exec >>/tmp/myDaemon.log

भविष्य की सभी मानक आउटपुट को उस फ़ाइल में भेजेगा। ऐसा इसलिए है क्योंकि execएक प्रोग्राम नाम के बिना बस कुछ पुनर्निर्देशन जादू करता है। से bashआदमी पेज:

यदि कमांड निर्दिष्ट नहीं है, तो कोई भी पुनर्निर्देशन वर्तमान शेल में प्रभावी होता है।

उक्त फाइल का प्रबंधन पाठ्यक्रम का एक और मुद्दा है।


क्या आप स्पष्ट कर सकते हैं कि यह रेखा कहाँ रखी जानी चाहिए? उस start-stop-daemonपंक्ति के ठीक बाद जो प्रारंभिक प्रश्न का उल्लेख है?
— अब्दुल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.