लिनक्स टी कमांड को कैसे समाप्त किया जा सकता है बिना आवेदन को मार डाले


19

मेरे पास एक बैश स्क्रिप्ट है जो तब तक चलती है जब तक लिनक्स मशीन चालू होती है। मैं इसे नीचे दिखाए अनुसार शुरू करता हूं:

( /mnt/apps/start.sh 2>&1 | tee /tmp/nginx/debug_log.log ) &

इसकी सराहना करने के बाद, मैं अपने ps आउटपुट में टी कमांड देख सकता हूं जैसा कि नीचे दिखाया गया है:

$ ps | grep tee
  418 root       0:02 tee /tmp/nginx/debug_log.log
3557 root       0:00 grep tee

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

monitor_debug_log_size() {
                ## Monitor the file size of the debug log to make sure it does not get too big
                while true; do
                                cecho r "CHECKING DEBUG LOG SIZE... "
                                debugLogSizeBytes=$(stat -c%s "/tmp/nginx/debug_log.log")
                                cecho r "DEBUG LOG SIZE: $debugLogSizeBytes"
                                if [ $((debugLogSizeBytes)) -gt 100000 ]; then
                                                cecho r "DEBUG LOG HAS GROWN TO LARGE... "
                                                sleep 3
                                                #rm -rf /tmp/nginx/debug_log.log 1>/dev/null 2>/dev/null
                                                kill -9 `pgrep -f tee`
                                fi
                                sleep 30
                done
}

मेरे आश्चर्य करने के लिए, टी कमान को मारना भी शुरू होता है। उदाहरण के लिए। ऐसा क्यों है? मैं टी कमांड को कैसे समाप्त कर सकता हूं, लेकिन क्या मेरा स्टार्ट.श जारी है? धन्यवाद।

जवाबों:


34

जब teeसमाप्त हो जाता है, तो इसे खिलाने वाली कमांड तब तक चलती रहेगी, जब तक कि यह अधिक आउटपुट लिखने का प्रयास नहीं करती। फिर इसे बिना पाठकों के साथ एक पाइप पर लिखने की कोशिश के लिए एक SIGPIPE (अधिकांश प्रणालियों पर 13) मिलेगा।

यदि आप SIGPIPE को फंसाने के लिए अपनी स्क्रिप्ट को संशोधित करते हैं और कुछ उपयुक्त कार्रवाई करते हैं (जैसे, आउटपुट लिखना बंद करें), तो आपको टी समाप्त होने के बाद इसे जारी रखने में सक्षम होना चाहिए।


बेहतर अभी तक, tee सभी को मारने के बजाय , सादगी के लिए विकल्प के logrotateसाथ उपयोग करें copytruncate

बोली के लिए logrotate(8):

copytruncate

पुरानी लॉग फ़ाइल को स्थानांतरित करने और वैकल्पिक रूप से एक नया बनाने के बजाय, प्रतिलिपि बनाने के बाद मूल लॉग फ़ाइल को अलग करें। इसका उपयोग तब किया जा सकता है जब कुछ प्रोग्राम को अपने लॉगफाइल को बंद करने के लिए नहीं कहा जा सकता है और इस प्रकार वह पिछले लॉग फाइल में हमेशा के लिए लिखना (जोड़ना) जारी रख सकता है। ध्यान दें कि फ़ाइल की प्रतिलिपि बनाने और उसे रौंदने के बीच बहुत कम समय का टुकड़ा है, इसलिए कुछ लॉगिंग डेटा खो सकता है। जब इस विकल्प का उपयोग किया जाता है, तो बनाने के विकल्प पर कोई प्रभाव नहीं पड़ेगा, क्योंकि पुरानी लॉग फ़ाइल जगह पर रहती है।


9
आप फ़ाइल को एपेंड मोड में खोलने के tee -aलिए भी उपयोग करना चाहते हैं tee, अन्यथा, टी उसी फ़ाइल पर लिखने के बाद आपको उसी ट्रंक के माध्यम से लिखेगा (और सिस्टम पर जो macOS की तरह विरल फ़ाइलों का समर्थन नहीं करता है। फ़ाइल के अनुभाग को उस स्थिति तक ले जाएं, जो डिस्क स्थान से दोगुना हो)।
स्टीफन चेज़लस

4
अन्य विकल्प यह होगा logger -sकि लॉगिंग का ध्यान रखने के लिए सिसलॉग के लिए पाइप किया जाए ( -sस्टडर पर भी प्रिंट किया जाए)।
स्टीफन चेज़लस

1
के लिए +1 logrotate। शानदार कार्यक्रम
दिमित्री कुद्रियात्सेव

2
या लकड़हारे के बजाय systemd और journald, systemd-cat का उपयोग कर एक प्रणाली पर। फिर आपको बहुत सारे आउटपुट फ़िल्टरिंग और मुफ्त में मिलते हैं।
ज़ैन लिंक्स

3

"क्यों" समझाते हुए

संक्षेप में: यदि लिखने में विफल होने के कारण प्रोग्राम से बाहर निकलने (डिफ़ॉल्ट रूप से) का कारण नहीं बना , तो हमें गड़बड़ होगी। गौर करें find . | head -n 10- आप findअपनी हार्ड ड्राइव के बाकी हिस्सों को स्कैन करते रहना नहीं चाहते हैं , इसके बाद headपहले से ही आवश्यक 10 लाइनें ले चुके हैं और आगे बढ़ गए हैं।

यह बेहतर है: अपने लकड़हारा के अंदर घुमाएँ

निम्नलिखित पर विचार करें, जो teeप्रदर्शन उदाहरण के रूप में बिल्कुल भी उपयोग नहीं करता है :

#!/usr/bin/env bash

file=${1:-debug.log}                     # filename as 1st argument
max_size=${2:-100000}                    # max size as 2nd argument
size=$(stat --format=%s -- "$file") || exit  # Use GNU stat to retrieve size
exec >>"$file"                           # Open file for append

while IFS= read -r line; do              # read a line from stdin
  size=$(( size + ${#line} + 1 ))        # add line's length + 1 to our counter
  if (( size > max_size )); then         # and if it exceeds our maximum...
    mv -- "$file" "$file.old"            # ...rename the file away...
    exec >"$file"                        # ...and reopen a new file as stdout
    size=0                               # ...resetting our size counter
  fi
  printf '%s\n' "$line"                  # regardless, append to our current stdout
done

यदि इस रूप में चलाया जाए:

/mnt/apps/start.sh 2>&1 | above-script /tmp/nginx/debug_log

... यह तब शुरू होगा जब 100KB से अधिक सामग्री मौजूद होने पर /tmp/nginx/debug_logफ़ाइल का नाम बदलकर /tmp/nginx/debug_log.old। क्योंकि लकड़हारा स्वयं ही रोटेशन कर रहा है, कोई टूटा हुआ पाइप नहीं है, कोई त्रुटि नहीं है, और रोटेशन होने पर कोई डेटा हानि खिड़की नहीं है - प्रत्येक पंक्ति एक फ़ाइल या किसी अन्य को लिखी जाएगी।

बेशक, देशी बाश में इसे लागू करना अक्षम है, लेकिन उपरोक्त एक उदाहरण है। ऐसे कई कार्यक्रम उपलब्ध हैं जो आपके लिए उपरोक्त तर्क को लागू करेंगे। विचार करें:

  • svlogdरनिट सूट से सर्विस लकड़हारा।
  • s6-log, स्कैनेट सूट से सक्रिय रूप से बनाए रखा गया विकल्प।
  • multilog प्रक्रिया पर्यवेक्षण और निगरानी टूलिंग के इस परिवार के पोते, डीजेबी डेमोंटोल्स से।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.