एक फ़ाइल को शून्य करने के लिए बिल्ली और '>' के बीच अंतर


23

क्या ये दो अलग-अलग कमांड हैं जो शून्य-आउट आउट फ़ाइलों के बारे में कैसे जाते हैं? क्या उत्तरार्द्ध पूर्व करने का एक छोटा तरीका है? पर्दे के पीछे क्या हो रहा है?

दोनों

$ cat /dev/null > file.txt

$ > file.txt 

मान जाना

-rw-r--r--  1 user  wheel  0 May 18 10:33 file.txt

जवाबों:


28

cat /dev/null > file.txtबिल्ली का एक बेकार उपयोग है

मूल रूप से cat /dev/nullबस catकुछ भी नहीं उत्पादन में परिणाम है । हाँ, यह काम करता है, लेकिन यह कई लोगों द्वारा पर आधारित है क्योंकि यह एक बाहरी प्रक्रिया को लागू करने में परिणत होता है जो आवश्यक नहीं है।
यह उन चीजों में से एक है जो सामान्य है क्योंकि यह आम है।

बस का उपयोग करना > file.txtअधिकांश गोले पर काम करेगा, लेकिन यह पूरी तरह से पोर्टेबल नहीं है। यदि आप पूरी तरह से पोर्टेबल चाहते हैं, तो निम्नलिखित अच्छे विकल्प हैं:

true > file.txt
: > file.txt

दोनों :और trueकोई डेटा आउटपुट नहीं करते हैं, और शेल बिलिन हैं (जबकि catएक बाहरी उपयोगिता है), इस प्रकार वे हल्के और अधिक 'उचित' हैं।

 

अद्यतन करें:

जैसा कि टायलर ने अपनी टिप्पणी में उल्लेख किया है, >| file.txtवाक्यविन्यास भी है ।

अधिकांश गोले में एक सेटिंग होती है जो उन्हें मौजूदा फ़ाइल के माध्यम से काट-छाँट करने से रोकेगी >। आपको >|इसके बजाय उपयोग करना चाहिए । यह मानवीय त्रुटि को रोकने के लिए है जब आप वास्तव में साथ जोड़ना चाहते थे >>। आप व्यवहार को चालू कर सकते हैं set -C

तो इसके साथ, मुझे लगता है कि किसी फ़ाइल को रौंदने का सबसे सरल, सबसे उचित और पोर्टेबल तरीका होगा:

:>| file.txt

2
कोलन कमांड को पोसिक्स में परिभाषित किया गया है । यह एक अशक्त ऑपरेशन है जो कमांडलाइन आर्ग्स का विस्तार करने के लिए मौजूद है।
कोजिरो

3
LOL, "बिल्ली का दुरुपयोग"
KM।

2
@kojiro :को POSIX द्वारा बिल्ट-इन किया जाना भी अनिवार्य है, और वास्तव में यह इससे अलग trueहै कि इसे "विशेष" बिल्ट-इन माना जाता है
jw013

2
noclobber के बारे में मत भूलना । >| fileअधिक स्पष्ट ट्रंकट है।
tylerl

1
कोई निर्माण trueकरने की आवश्यकता नहीं है और यह परंपरागत रूप से नहीं था। :बॉर्न परिवार के सभी गोले में बनाया गया है। :POSIX प्रति एक विशेष अंतर्निहित है (इसलिए : > fileयदि filePOSIX गोले में लिखने के लिए खुला नहीं हो सकता है तो शेल से बाहर निकल जाएगा ) और trueनहीं है। POSIX में भी उल्लेख है कि कुछ प्रणालियों की तुलना में :अधिक कुशल हो सकता है true
स्टीफन चेज़लस

23

पोर्टेबिलिटी के संदर्भ में:

                      Bourne POSIX  zsh    csh/tcsh  rc/es  fish
> file                Y      Y      N(1)   N(1)      N      N
: > file              N/Y(2) Y(3)   Y      Y(4)      N(5)   N(5)
true > file           Y(5)   Y      Y      Y(5)      Y(5)   Y(5)
cat /dev/null > file  Y(5)   Y      Y(5)   Y(5)      Y(5)   Y(5)
eval > file           Y(3,8) Y(3)   Y      Y(6)      Y      Y
cp /dev/null file (7) Y(5)   Y      Y(5)   Y(5)      Y(5)   Y(5)
printf '' > file      Y(5)   Y      Y      Y(5)      Y(5)   Y

टिप्पणियाँ:

  1. बिना किसी कमांड के रीडायरेक्ट के लिए shया kshएमुलेशन को छोड़कर , zsh में, एक डिफॉल्ट कमांड को माना जाता है (केवल catस्टड रिडायरेक्शन के लिए एक पेजर, अन्यथा), जिसे NULLCMD और READNULLCLCD चर के साथ ट्यून किया जा सकता है। यह इसी तरह की सुविधा से प्रेरित है(t)csh
  2. :UnixV7 में शुरू में पुनर्निर्देशन नहीं किया :गया था क्योंकि एक टिप्पणी नेता और एक अशक्त कमांड के बीच आधे रास्ते की व्याख्या की गई थी। बाद में वे सभी बिल्डिंस के लिए पसंद करते थे, यदि पुनर्निर्देशन विफल हो जाता है, जो शेल से बाहर निकलता है।
  3. :और evalविशेष अंतर्निहित होने के नाते, यदि पुनर्निर्देशन विफल हो जाता है, तो शेल से बाहर निकलता है ( bashकेवल POSIX मोड में ऐसा करता है)।
  4. दिलचस्प है, में (t)csh, यह एक अशक्त लेबल (के लिए goto) को परिभाषित कर रहा है , इसलिए goto ''वहां शाखा होगी। यदि पुनर्निर्देशन विफल रहता है, जो शेल से बाहर निकलता है।
  5. जब तक / अगर इसी आदेश में उपलब्ध है $PATH( :आम तौर पर नहीं है, true, cat, cpऔर printfआम तौर पर कर रहे हैं (इसे POSIX उन्हें आवश्यकता है))।
  6. यदि पुनर्निर्देशन विफल रहता है, जो शेल से बाहर निकलता है।
  7. यदि fileएक गैर-मौजूदा फ़ाइल के लिए एक सहानुभूति है, तो कुछ cpकार्यान्वयन जैसे कि GNU के इसे बनाने से इंकार कर देगा।
  8. बॉर्न शेल के शुरुआती संस्करणों ने हालांकि पुनर्निर्देशित बिल्डरों का समर्थन नहीं किया

सुव्यवस्था के संदर्भ में:

(यह खंड अत्यधिक व्यक्तिपरक है)

  • > file। यह >एक संकेत या एक टिप्पणी की तरह बहुत ज्यादा लग रहा है। यह भी प्रश्न मैं पढ़ते समय पूछूंगा कि (और अधिकांश गोले उसी के बारे में शिकायत करेंगे) क्या आउटपुट वास्तव में आप पुनर्निर्देशित कर रहे हैं?
  • : > file:नो-ऑप कमांड के रूप में जाना जाता है। ताकि एक खाली फाइल उत्पन्न करने के रूप में सीधे पढ़ता है। हालाँकि, यहाँ फिर से, :आसानी से याद किया जा सकता है और / या एक संकेत के रूप में देखा जा सकता है।
  • true > file: बूलियन को पुनर्निर्देशन या फ़ाइल सामग्री के साथ क्या करना है? यहाँ क्या मतलब है? पहली बात यह है कि मेरे मन में आता है जब मैंने पढ़ा है कि
  • cat /dev/null > fileCONCATENATE /dev/nullमें file? catअक्सर आदेश फ़ाइल की सामग्री डंप के रूप में देखा जा रहा है, कि अभी भी समझ बनाने के कर सकते हैं: की सामग्री डंप में खाली फ़ाइलfile , एक जटिल रास्ते की तरह एक सा कहने के लिए cp /dev/null file, लेकिन अभी भी समझ में आता है।
  • cp /dev/null fileखाली फ़ाइल की सामग्री की प्रतिलिपि बनाता है file। समझ में आता है, हालांकि किसी को यह नहीं पता है कि cpडिफ़ॉल्ट रूप से कैसे करना है, आपको लगता है कि आप fileएक nullउपकरण बनाने की कोशिश कर रहे हैं ।
  • eval > fileया eval '' > file। कुछ भी नहीं चलाता है और इसके उत्पादन को पुनर्निर्देशित करता है file। मेरी समझ मे आ रहा है। अजीब बात है कि यह एक सामान्य मुहावरा नहीं है।
  • printf '' > file: स्पष्ट रूप से एक फ़ाइल में कुछ भी प्रिंट नहीं करता है। वह जो मेरे लिए सबसे ज्यादा मायने रखता है।

प्रदर्शन के मामले में

अंतर यह है कि हम शेल शेल का उपयोग कर रहे हैं या नहीं। यदि नहीं, तो एक प्रक्रिया को कांटा जाता है, कमांड लोड और निष्पादित होता है।

evalसभी गोले में निर्मित होने की गारंटी है। :जहाँ भी यह उपलब्ध है (बॉर्न / csh पसंद) निर्मित है। trueबॉर्न-जैसे गोले में ही बनाया गया है।

printfबिल्ट-इन सबसे आधुनिक बोर्न-जैसे गोले हैं और fish

cpऔर catआमतौर पर बिल्ट-इन नहीं होते हैं।

अब cp /dev/null fileशेल पुनर्निर्देशन को लागू नहीं करता है, इसलिए चीजें इस तरह हैं:

find . -exec cp /dev/null {} \;

से अधिक कुशल होने जा रहे हैं:

find . -exec sh -c '> "$1"' sh {} \;

(हालांकि जरूरी नहीं:

find . -exec sh -c 'for f do : > "$f"; done' sh {} +

)।

व्यक्तिगत रूप से

व्यक्तिगत रूप से, मैं : > fileबॉर्न-जैसे गोले में उपयोग करता हूं , और इन दिनों बॉर्न-जैसे गोले के अलावा कुछ भी उपयोग नहीं करता हूं।


किस बारे में dd of=file count=0?
कोजिरो

2
@kojiro, dd(सोलारिस 10 की तरह कम से कम) के कुछ कार्यान्वयन के साथ , count=0नजरअंदाज कर दिया जाता है। dd if=/dev/null of=fileअधिक पोर्टेबल होगा। किसी भी मामले में, यह शेल से स्वतंत्र है।
स्टीफन चेजलस

ठीक है, लेकिन यह शामिल करने के लिए कम योग्य नहीं है cp /dev/null file, है ना?
कोजिरो

2
@ कोकोजी, cp /dev/null fileएक सामान्य मुहावरा है। मैं उन लोगों को सीमित कर रहा हूं, यह बिंदु सभी संभावित तरीकों को सूचीबद्ध करने का नहीं है।
स्टीफन चेज़लस

5

आप देखना चाह सकते हैं truncate, जो ठीक यही करता है: किसी फ़ाइल को काट देना।

उदाहरण के लिए:

truncate --size 0 file.txt

यह संभवतः उपयोग करने की तुलना में धीमा है true > file.txt

हालांकि मेरा मुख्य बिंदु यह है: truncateफ़ाइलों को ट्रंक करने के लिए अभिप्रेत है, जबकि> किसी फ़ाइल को रौंदने का साइड इफेक्ट है।


2
Truncate अच्छा है जब आप किसी फ़ाइल को 0. के अलावा किसी अन्य चीज़ से काटना चाहते हैं, तो भी , बिना शेल के भी एक अजीब कथन है: क्या आप किसी ऐसे संदर्भ का वर्णन कर सकते हैं जहाँ truncateउपलब्ध होगा, लेकिन न तो >और न ही unistdC लाइब्रेरी उपलब्ध होगी?
कोजिरो

ज़रुरी नहीं। उपलब्ध स्क्रिप्ट या प्रोग्रामिंग भाषा के लिए संभवतः अधिक सुरुचिपूर्ण समाधान है।
फेबियन

3
truncateएक फ्रीबीएसडी उपयोगिता है, अपेक्षाकृत हाल ही में (2008) जीएनयू कोर्यूटिल्स में जोड़ी गई (हालांकि --sizeजीएनयू लॉन्ग ऑप्शन स्टाइल जीएनयू विशिष्ट है), इसलिए यह गैर-जीएनयू-या-फ्रीबीएसडी सिस्टम में उपलब्ध नहीं है, और यह पुराने जीएनयू सिस्टम में उपलब्ध नहीं है, मैं यह नहीं कहूंगा कि यह पोर्टेबल है। cp /dev/null fileशेल पुनर्निर्देशन के बिना काम करेगा और अधिक पोर्टेबल होगा।
स्टीफन चेजालस

ठीक है, मैं उस पोर्टेबिलिटी टिप्पणी को हटा दूंगा। हालांकि आपकी हाल की परिभाषा अलग-अलग है।
फाबियान

2

इसका उत्तर थोड़ा सा इस बात पर निर्भर करता है कि file.txtयह क्या है, और प्रक्रिया इसे कैसे लिखती है!

मैं एक सामान्य उपयोग के मामले का हवाला देता हूँ: आपके पास एक बढ़ती हुई लॉगफ़ाइल है file.txt, और इसे घुमाना चाहते हैं।

इसलिए आप उदाहरण के लिए कॉपी,, file.txtमें file.txt.save, तो काटना file.txt

इस परिदृश्य में, यदि फ़ाइल द्वारा नहीं खोला गया है another_process(उदाहरण के लिए: another_processउस फ़ाइल के लिए आउटपुट प्रोग्राम हो सकता है, उदाहरण के लिए कोई प्रोग्राम लॉगिंग कुछ), तो आपके 2 प्रस्ताव बराबर हैं, और दोनों अच्छी तरह से काम करते हैं (लेकिन 2 के रूप में पसंद किया जाता है) पहला "cat / dev / null> file.txt" बिल्ली का एक बेकार उपयोग है और यह भी खुलता और पढ़ता है / dev / null)।

लेकिन असली परेशानी यह होगी कि क्या other_processवह अभी भी सक्रिय है, और अभी भी एक खुला हैंडल file.txt पर जा रहा है।

फिर, 2 मुख्य मामले उत्पन्न होते हैं, other processजो फ़ाइल को खोलने पर निर्भर करता है :

  • यदि other_processइसे सामान्य तरीके से खोलता है, तो हैंडल अभी भी फ़ाइल में पूर्व स्थान की ओर इशारा करेगा, उदाहरण के लिए 1200 बाइट्स ऑफसेट। इसलिए अगला लेखन ऑफसेट 1200 पर शुरू होगा, और इस तरह आपके पास फिर से 1200bytes (+ जो भी अन्य_प्रोसेस ने लिखा है) की एक फ़ाइल होगी, जिसमें 1200 प्रमुख अशक्त अक्षर होंगे! आप जो चाहते हैं , मैं नहीं मानता।

  • यदि "एपेंड मोड" में other_processखोला file.txtगया है, तो हर बार जब यह लिखता है, तो पॉइंटर सक्रिय रूप से फ़ाइल के अंत की तलाश करेगा। इसलिए, जब आप इसे काटते हैं, तो यह बाइट 0 तक "तलाश" करेगा, और आपके बुरे दुष्प्रभाव नहीं होंगे! यह वही है जो आप चाहते हैं ... (आमतौर पर!)

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

संदर्भ: क्लीनर की व्याख्या के लिए /programming//a/16720582/1841533 , और /programming//a/984761/1841533 पर लॉगिंग सामान्य और अपेंड मोड के बीच अंतर का एक अच्छा लघु उदाहरण


2
इस उत्तर का बहुत कम वास्तव में प्रासंगिक है या प्रश्न का उत्तर देता है। A cat /dev/null > fileऔर a के बीच का अंतर एक > fileहै cat /dev/nullऔर इससे फ़ाइल में कोई अंतर नहीं पड़ता है।
jw013

@ jw013: सच! लेकिन मैं सिर्फ "आप क्या चाहते हैं / क्या नहीं चाहते हैं" जानकारी को फिर से बताने के लिए प्रश्न का अवसर लेना चाहते थे, क्योंकि यह बहुत अच्छी तरह से ज्ञात नहीं है, और लॉग को घुमाने की कोशिश करने वाले किसी व्यक्ति को हिट कर सकता है (एक सामान्य मामला जहां आप चाहते हैं एक फ़ाइल को काटें)।
ओलिवियर दुलैक

1
हर चीज के लिए एक समय और एक जगह होती है। आपकी जानकारी किसी अन्य संदर्भ में उपयोगी हो सकती है, लेकिन यह यहां नहीं है - आपको इसके लिए अधिक उपयुक्त स्थान ढूंढना चाहिए क्योंकि लॉग को घुमाने की कोशिश करने वाला कोई भी व्यक्ति इस पूरी तरह से असंबंधित पुनर्निर्देशन प्रश्न में नहीं दिखता है। यहाँ आपका जवाब एक डिजिटल खरपतवार के बराबर है, जिस तरह मकई के खेत के बीच में एक अन्यथा उपयोगी कद्दू का पौधा खरपतवार माना जाएगा।
jw013

1

मुझे यह पसंद है और अक्सर इसका इस्तेमाल करते हैं क्योंकि यह क्लीनर दिखता है और ऐसा नहीं है कि किसी ने दुर्घटना से वापसी की कुंजी को मारा:

echo -n "" > file.txt

एक अंतर्निहित भी होना चाहिए?


3
किसी फ़ाइल को शून्य-आउट करने के कई तरीके हैं। मुझे लगता है कि के.एम. केवल सवाल में दिखाए गए दो तरीकों के बीच अंतर को समझने में दिलचस्पी थी।
डीआरएस

6
कई echoकार्यान्वयन समर्थन नहीं करते हैं -n(और -n<SPC><NL>यहाँ उत्पादन printf '' > file.txtहोगा) अधिक पोर्टेबल (कम से कम आधुनिक / POSIX प्रणालियों में) होगा।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.