आप 'बिल्ली / देव / अशक्त> / वर / लॉग / संदेश' क्यों देंगे?


77

इस बैश स्क्रिप्टिंग उदाहरण पृष्ठ पर लेखक इस स्क्रिप्ट को प्रस्तुत करता है:

# Cleanup
# Run as root, of course.

cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Log files cleaned up."

आप cat /dev/nullकुछ भी क्यों करेंगे ? मैं समझ नहीं पा रहा हूँ कि यहाँ क्या इरादा है (क्या यह उपयोग करने के while TRUE; sleep 1; elihwलिए पसंद है {some busy program}?)। फिर भी लेखक इसे "असामान्य कुछ भी नहीं" कहता है।

जवाबों:


41

आप आमतौर पर cat /dev/null > [something]जब आप यह सुनिश्चित करना चाहते हैं कि वास्तविक फ़ाइल स्थिति में रुकावट का शून्य जोखिम है, तो फ़ाइल सामग्री को मिटा दें। फ़ाइल की सामग्री स्पष्ट रूप से cat /dev/nullअभी तक फ़ाइल से मिटा दी जाएगी - जैसा कि यह मौजूद है और फाइल सिस्टम के लिए जाना जाता है, जिस पर यह रहता है - अभी भी एक ही इनोड नंबर, स्वामित्व और अनुमतियों के साथ रहेगा।

एक लॉग फ़ाइल के मामले में, यह हो सकता है कि लॉग फ़ाइल स्वयं किसी अन्य प्रक्रिया द्वारा "उपयोग में" चिह्नित हो। इसलिए, उदाहरण के लिए- a rm /var/log/messages && touch /var/log/messagesअन्य प्रक्रियाओं के लिए विघटनकारी होगा और चोक करने के लिए चल रही प्रक्रियाओं का कारण हो सकता है। मतलब एक ऐसी प्रक्रिया जो किसी तरह से फाइल से जुड़ी एक विशिष्ट इनोड नंबर पर लॉक हो जाती है /var/log/messagesऔर अचानक घबरा कर कह सकती है, “अरे! क्या हुआ /var/log/messages? ”भले ही फाइल अभी भी वहीं है। स्वामित्व और अनुमतियों के साथ संभावित मुद्दों का उल्लेख नहीं करने के लिए गलत तरीके से बनाए गए हैं।

फ़ाइल के उपयोग / स्थिति में इस अनिश्चितता के कारण cat /dev/null > [something]सिस्टम एडिम्न्स द्वारा उपयोग को प्राथमिकता दी जाती है जो लॉग को खाली करना चाहते हैं, लेकिन पहले से मौजूद प्रक्रियाओं के संचालन में संभावित हस्तक्षेप नहीं करना चाहते हैं।

इसके अलावा, आप लेखक से जुड़े पेज के संदर्भ में निम्नलिखित बताते हैं:

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

तो "असामान्य कुछ भी नहीं" लेखक का उल्लेख है कि उस विशिष्ट बैश स्क्रिप्ट की पूरी अवधारणा के संबंध में है: यह सिर्फ साधारण आदेशों का एक सेट है जिसे केवल कमांड लाइन से आसानी से चलाया जा सकता है लेकिन पाठ फ़ाइल में हमेशा के लिए रखा जाता है बार-बार उन्हें फिर से लिखने से बचें।


10
@jlliagre "जीवित रखे जाने" वाली एकमात्र चीज़ उस प्रश्न का संदर्भ है जो इस बात पर केंद्रित है कि मूल लेखक ऐसा क्यों करेगा। यदि आप "मिथक" को फैलाने के लिए अभेद्य हैं, तो कृपया एक उत्तर दें जो मूल लेखक की कोडिंग पद्धति के साथ-साथ इस बात के परिप्रेक्ष्य में संदर्भ प्रदान करता है कि आप इसे अन्य तरीकों से क्यों बदल सकते हैं।
जेकगोल्ड

7
@jlliagre साइरस का उत्तर मूल प्रश्न को संबोधित नहीं करता है कि मूल लेखक ने उस पद्धति का उपयोग क्यों किया होगा और न ही इसके पीछे का कारण। उल्लिखित ट्यूटोरियल काफी पुराना है और यथोचित रूप से स्वीकृत है। यह गलत नहीं है और न ही इसे "शहरी किंवदंती" माना जाता है। बल्कि यह उस तरह से एक व्यक्ति कोड है जिस तरह से एक अन्य व्यक्ति कोड। इतना सरल है। यह एक शैली का मुद्दा है जिसका विश्वसनीयता या प्रदर्शन पर कोई नकारात्मक प्रभाव नहीं है।
जेकगोल्ड

3
truncate -s 0एक ही काम करेगा और कम मुहावरेदार होगा। हालांकि, शेल प्रोग्रामर एक रूढ़िवादी गुच्छा हैं और किसी को पुराने सिस्टम से सामना करना पड़ सकता है या उस आदेश की कमी होने के लिए पर्याप्त रूप से निराला हो सकता है।
Schwern

5
@skift cat /dev/null > /foo/barफ़ाइल को काट देता है; echo "" > /foo/barइसे काटता है और फिर एक एकल न्यूलाइन वर्ण लिखता है।
डेविड

2
आरएम और टच पर इस पद्धति का एक और लाभ यह है कि स्वामित्व और अनुमतियां बनी रहती हैं।
jjmontes 13

121

आप किसी भी चीज़ पर कैट / देव / अशक्त क्यों होंगे?

आप इनोड को बरकरार रखते हुए एक फ़ाइल सामग्री को अलग करने के लिए करेंगे। पढ़ने या लिखने के लिए उस फ़ाइल को खोलने वाले सभी प्रोग्राम इस तथ्य से बाहर प्रभावित नहीं होंगे कि फ़ाइल का आकार शून्य पर रीसेट हो जाएगा।

अक्सर पाया जाने वाला फर्जी विकल्प फ़ाइल को हटा रहा है और इसे फिर से बना रहा है:

rm file
touch file

या इसी तरह:

mv file file.old
gzip file.old
touch file

समस्या यह है कि ये विधियाँ पुरानी फ़ाइल को हटाने की समय पर खुली हुई फ़ाइल को खोलने वाली जो भी प्रक्रियाएँ लिखी जा रही हैं, उन्हें रोकने से रोकती नहीं हैं। यूनिक्स फ़ाइल सिस्टम के अंतर्गत आने का कारण, जब आप किसी फ़ाइल को हटाते हैं, तो आप केवल उसका नाम (पथ) उसकी सामग्री (इनोड) से हटाते हैं। जब तक पढ़ने या लिखने के लिए खुला होने की प्रक्रिया नहीं होती तब तक इनोड को जीवित रखा जाता है।

यह कई नकारात्मक प्रभावों की ओर जाता है: फ़ाइल हटाने के बाद लिखे गए लॉग खो जाते हैं क्योंकि हटाए गए फ़ाइल को खोलने का कोई सीधा / पोर्टेबल तरीका नहीं है। जब तक एक प्रक्रिया हटाए गए फ़ाइल को लिख रही है, तब तक इसकी सामग्री अभी भी फ़ाइल सिस्टम पर स्थान का उपयोग कर रही है। इसका मतलब है कि यदि आप फ़ाइल को हटाते / बनाते हैं क्योंकि यह आपकी डिस्क को भर रहा था, तो डिस्क भर जाती है। इस बाद के मुद्दे को ठीक करने का एक तरीका लकड़हारा प्रक्रियाओं को फिर से शुरू करना है, लेकिन आप ऐसा नहीं करना चाहते हैं कि महत्वपूर्ण सेवाओं और मध्यस्थ लॉग के लिए निश्चित रूप से खो जाएगा। इस तथ्य के कारण भी दुष्प्रभाव हैं कि आपके द्वारा बनाई गई फ़ाइल में मूल एक से अधिक अनुमतियाँ, स्वामी और समूह नहीं हो सकते हैं। उदाहरण के लिए यह लॉग एनालाइज़र को नई बनाई गई फ़ाइल को पढ़ने से रोक सकता है, या इससे भी बदतर, लॉगिंग प्रक्रिया को अपने लॉग को लिखने से रोक सकता है।

पहला तरीका, cat /dev/null > fileलक्ष्य को ठीक से प्राप्त करना , हालांकि, एक कठिन शहरी कथा के बावजूद, इसका cat /dev/nullहिस्सा बिल्कुल उपयोगी नहीं है। यह एक छद्म फ़ाइल खोलता है जो डिज़ाइन द्वारा खाली है, यह इसमें से कुछ भी पढ़ने में विफल रहता है और अंत में बस बाहर निकलता है। इस कमांड का उपयोग करना तब कीस्ट्रोक्स, बाइट्स, सिस्टम कॉल और सीपीयू साइकल की बर्बादी है और इसे बिना किसी कमांड के :, अधिकांश शेल के साथ, निस्संदेह तेजी से नो-ऑप कमांड द्वारा या किसी भी कार्यात्मक परिवर्तन के बिना बदला जा सकता है ।

मुझे समझाने की कोशिश करो कि कितना बेकार cat /dev/nullहै। मान लीजिए कि आपका लक्ष्य एक गिलास खाली करना है।

  • आप सबसे पहले इसमें से कोई तरल निकालते हैं। यह पर्याप्त है और वास्तव में क्या है ( > file) यह तथ्य बताता है कि पुनर्निर्देशन हमेशा पहले संसाधित होते हैं।

  • फिर, आप एक खाली बोतल ( /dev/null) उठाते हैं और इसे खाली गिलास ( cat) में डालते हैं । यह व्यर्थ कदम है ...

यदि आप अपने लिंक किए गए दस्तावेज़ को अंत तक पढ़ते हैं , तो आप स्क्रिप्ट के वर्धित संस्करण से इस पंक्ति में टिप्पणियों को देख सकते हैं:

    cat / dev / null> wtmp #   ':> wtmp' और '> wtmp' का एक ही प्रभाव है।

उनके पास वास्तव में है; बहुत बुरा cat /dev/nullकोड में रखा गया था।

इसका मतलब है कि निम्नलिखित कोड सभी सामान्य कवच (दोनों cshऔर shपरिवार) के साथ काम करेंगे :

cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."

और इस तरह, बॉर्न सिंटैक्स का उपयोग सभी के गोले के साथ काम करेंगे ash, bash, ksh, zshऔर पसंद:

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

हालाँकि, ध्यान दें कि प्राचीन, प्री-पॉस बॉर्न गोले के साथ, इनमें से कोई भी आदेश, cat /dev/nullएक फ़ाइल को काट नहीं सकता है यदि इसे बाद में चल रहे शेल स्क्रिप्ट द्वारा इसे लिखा जाता है। एक शून्य बाइट फ़ाइल के बजाय, यह एक विरल फ़ाइल होगी, जिसका आकार अपरिवर्तित होगा। ऐसा ही होगा यदि फ़ाइल एक प्रक्रिया द्वारा लिखी गई स्थिति के अनुसार लिखती है, जो यह सोचती है कि लिखने से पहले वह एक है।

यह भी सावधान रहें कि कुछ वैकल्पिक समाधानों में अक्सर किसी फाइल में खामियां होने का सुझाव दिया जाता है।

  • निम्नलिखित दोनों ही काम नहीं करते हैं। परिणामी फ़ाइल खाली नहीं है, लेकिन एक खाली लाइन है। यह लॉग फ़ाइलों को wtmpउस स्टोर की तरह तय चौड़ाई के रिकॉर्ड को तोड़ देगा ।

    echo > file
    echo "" > file
    
  • बीएसडी shविकल्प पर आधारित अगला पोर्टेबल नहीं है, पोसिक्स गूंज के लिए किसी भी अनुमति के विकल्प को निर्दिष्ट नहीं करता है, इसलिए आप एक फाइल को " -n" के साथ एक पंक्ति के साथ समाप्त कर सकते हैं :

    echo -n > file
  • यह एक या तो सिस्टम V shएस्केप अनुक्रम का उपयोग करके पोर्टेबल नहीं है । कुछ गोले एक फाइल बनाएंगे जिसमें " \c" के साथ एक लाइन होगी :

    echo "\c" > file
  • यह एक काम करने के लिए डिज़ाइन की गई कमांड का उपयोग करता है। समस्या का उपयोग truncateपोर्टेबल नहीं है क्योंकि यह आदेश, POSIX द्वारा निर्दिष्ट नहीं किया जा रहा है, एक यूनिक्स / लिनक्स सिस्टम से गायब हो सकता है।

    truncate -s 0

अंत में, यहां कुछ विकल्प दिए गए हैं जो पोर्टेबल हैं और ठीक से काम करेंगे:

  • स्पष्ट रूप से फ़ाइल को एक रिक्त स्ट्रिंग मुद्रित करना:

    printf "" > file
  • trueआदेश का उपयोग करना, जो सख्ती से एक से :अधिक किसी भी पठनीय के बराबर है :

    true > file

1
@JonathanLeffler मेरा मानना ​​है कि यह सभी मौजूदा cshकार्यान्वयन का हिस्सा है, हालांकि यह आवश्यक रूप से प्रलेखित नहीं है। सोलारिस csh मैनुअल पेज से : Null command. This command is interpreted, but performs no action.। मुझे tcshमैनुअल पेज या मूल बीएसडी cshवाले दोनों में ही इसका कोई उल्लेख नहीं मिला लेकिन यह वाक्य रचना हमेशा काम कर सकती है।
जलीगरे '

6
लेखन cat /dev/nullका एक कारण आपके इरादों को स्पष्ट करना है।
डेविड डेम 8'14

1
@ दाविद समझदार होगा लेकिन आपका बयान तथ्य जाँच का विरोध नहीं करता है। मैंने इस शैल मुहावरे को शायद कुछ दशकों तक देखा है। जब मुझे लेखक से इसके पीछे का तर्क पूछने का अवसर मिला , तो मुझे हमेशा/dev/null शून्य बाइट्स को इंजेक्ट करने के लिए एक कुशल तरीका का उपयोग करने के बारे में बिना सोचे समझे , वैसे भी उपयोग करने :या कुछ भी नहीं की तुलना में अधिक विश्वसनीय है । इस पृष्ठ में, साइरस का जवाब जो कि बहुत ही सटीक था, लेकिन सीधे-सीधे इस बिंदु पर शून्य वोट थे, जबकि जेकगॉल्ड के पास जो इस तथ्य cat /dev/nullको चुनौती दे रहा था, वह एक नो-ऑप (हमारी टिप्पणियाँ देखें) में पहले से ही कम से कम चार वोट थे।
जूलियाग्रे

2
@jlliagre शैल का मेरा ज्ञान काफी बुनियादी है, इसलिए मैं शायद सबसे अच्छी आबादी का लक्ष्य नहीं हूं; लेकिन एक नंगे >या :स्पष्ट नहीं है। मैं मानता हूं कि यह शर्म की बात है कि मिथकों को इसके इस्तेमाल के कारण प्रचारित किया गया है।
डेविड

4
@ दाविद्म यदि आप वास्तव में पुनर्निर्देशन से पहले कुछ स्पष्ट करना चाहते हैं, तो मैं सुझाव दूंगा कि printf "" > fileदोनों पोर्टेबल (POSIX) और हल्के हैं जो अक्सर शेल बिल्डिन के रूप में लागू होते हैं।
जलीगेरे

6

यह फ़ाइल को शून्य आकार में लाने का एक बोझिल तरीका है।

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

यह सिंटैक्स प्रत्येक शेल में काम नहीं करेगा।
रीइनियरियरपोस्ट

2
सही बात। प्रश्न केवल "बैश" के साथ टैग किया गया है।
सायरस

@reinierpost यह सभी बॉर्न-शैली के गोले में काम करेगा, है ना? चलो कोई बात नहीं csh
बरमार

: > messagesभी काम करता है। :या trueआज्ञाओं के लिए अधिक स्पष्ट विकल्प हैं जो कुछ भी नहीं छापते हैं और सही वापस आते हैं।
पीटर कॉर्डेस

-3

एक खुली फ़ाइल को छोटा करने के लिए। यह बराबर है, और अधिक समझदार है:

echo -n > /var/log/messages

(न्यूलाइन से बचने के लिए जोड़ा गया)


3
यह वास्तव में अधिक समझने योग्य है लेकिन दुर्भाग्य से एक समकक्ष नहीं है। यह wtmpमामले की तरह कार्यात्मकताओं को भी तोड़ देगा । देखिये मेरा अपडेटेड जवाब।
jlliagre

इको-एन न्यूलाइन से बचा जाता है।
bbaassssiiee

6
यह वास्तव में अगर आप उपयोग करने के लिए सुनिश्चित हैं bash, -nअन्यथा सभी बॉर्न गोले में काम करने की गारंटी नहीं है।
जलीगेरे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.