cp अधिलेखित बनाम rm तब cp


18

जब मैं वर्तमान में लॉन्च की गई बाइनरी फ़ाइल को अधिलेखित करने का प्रयास करता हूं, तो cpओवरराइट करने में विफल रहता है, लेकिन rmयह तब संभव है cp। उदाहरण के लिए:

user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile 
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile 
user@poste:~$ sudo cp /tmp/binaryFile  binaryFile 
user@poste:~$ file binaryFile 
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped

कोई विचार क्यों?


2
दिलचस्प थोड़ा धागा, लेकिन यूनिक्स / लिनक्स पर होना चाहिए। IMO।
अंडरस्कोर_ड

जवाबों:


41

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

लेकिन दूसरे मामले में, आप वास्तव में पुरानी फ़ाइल की सामग्री को नहीं बदल रहे हैं - आप इसके स्थान पर एक नई फ़ाइल बना रहे हैं , जबकि पुराना केवल फ़ाइल नाम खो देता है, लेकिन इसकी सामग्री को अछूता रखता है।

(याद रखें कि तकनीकी रूप से फाइलें डिलीट rmनहीं करता है , यह सिर्फ डायरेक्टरी लिंक हटाता है - उसी फाइल में और लिंक जोड़ता है। केवल तभी जब किसी फाइल में कोई लिंक नहीं है और कोई ओपन फाइल रेफरेंस नहीं है, यह अपने आप डिलीट हो जाता है।)ln

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


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

2
यही कारण है कि जब आप किसी रनिंग प्रोसेस की कुछ लॉग फाइल को डिलीट करते हैं तो df कमांड सही साइज को वापस नहीं करता है जब तक आप प्रोसेस को रोक नहीं देते
M4rty

क्या इस झूलने वाले इनोड के लिए एक नया कार्यक्रम (रूट प्राइवेटलाइज़ के साथ) खोजने और बनाने के लिए कोई रास्ता है? मुझे लगता है कि ऐसे कार्यक्रम हैं जो इसे "सुरक्षा सुविधा" के रूप में उपयोग करते हैं, इसलिए पूरी कहानी को समझना दिलचस्प है।
बेनपैन

3
@BenPen: लिनक्स पर, हां - /proc/*/fdइसे एक्सेस करने के लिए उपयोग करें, और फाइल सिस्टम के लिए एक नया लिंक जोड़ने के लिए वैकल्पिक रूप से लिंकैट ()
user1686

3
@BenPen और grawity: असल में, आप निर्देशिका संरचना में एक आइनोड वापस लिंक कर सकते हैं नहीं है, तो यह शून्य संबंध हैं, यहां तक कि के साथ linkat(), सुरक्षा कारणों से । : (जब तक यह साथ बनाया गया था इस नियम के अपवाद open(O_TMPFILE)तो यह शुरू कर दिया आप कोशिश करते हैं, शून्य लिंक के साथ।) linkat()भी रूट के रूप में रिटर्न ENOENT,। वास्तव में चलाने के लिए एक पर्ल स्क्रिप्ट के लिए उस सवाल पर मेरा जवाब देखें linkatऔर साबित करें कि यह रूट के रूप में भी काम नहीं करता है: /
पीटर कॉर्ड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.