मैं केवल-पढ़ने के लिए फ़ाइल क्यों संशोधित कर सकता हूं?


42

लघु प्रश्न:

हम व्यवस्थापक होने के बिना भी :+ w+ q+ का उपयोग करके विम में केवल-पढ़ने के लिए फ़ाइल में हेरफेर क्यों कर सकते हैं !?

लंबा प्रश्न:

मेरे पास एक पाठ फ़ाइल (myFile.txt) है जो केवल सभी के लिए पढ़ी जाती है:

navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

मैं इसे बिना विशेषाधिकारों के विम के साथ खोल सकता हूं:

navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 

मैं इसे संशोधित करता हूं और दबाता हूं: Esc+ :+ w+ q+ Enterऔर मैं यह त्रुटि संदेश देखता हूं:

E45: 'readonly' option is set (add ! to override)

अब तक, सब कुछ समझ में आता है। लेकिन जब मैं दबाता हूं: Esc+ :+ w+ q+ !+ Enter, विम परिवर्तन को बचाता है।

मैं Ubuntu 16.04 और VIM 7.4 का उपयोग कर रहा हूं।


1
क्या आप उस निर्देशिका के मालिक हैं जो फ़ाइल में है?
रोब

हाँ, यह एक बड़ी समस्या होगी अन्यथा :)
Rob

11
एक फ़ाइल को संशोधित करना और एक फ़ाइल की जगह दो अलग-अलग चीजें हैं जो अलग-अलग अनुमति आवश्यकताओं के साथ हैं।
डेविड श्वार्ट्ज

1
आप इस पर एक नज़र रखना चाहते हो सकता है । यह मूल रूप से आपके प्रश्न का उत्तर देता है और @DavidSchwartz के रूप में सही ढंग से बताया गया है :Modifying a file and replacing a file are two different things
पणगीतिस तबकिस

@PanagiotisTabakis बहुत अच्छा लगता है यह शानदार है .. फ़ाइल को पढ़ने-लिखने और फिर से बनाने के लिए चामोड है यदि आप इसे अपनाते हैं .. LOVE IT :)
Rob

जवाबों:


58

जैसा कि @Rob में पहले ही उल्लेख किया गया है , आप केवल ऐसा कर सकते हैं यदि आपके पास फ़ाइल युक्त निर्देशिका तक पहुंच है। उदाहरण के लिए, फ़ाइल में समान कार्य करने का प्रयास /etcविफल हो जाएगा।

यह कैसे vim कर रहा है, यह फ़ाइल को हटाता है और इसे फिर से बनाता है। इसका परीक्षण करने के लिए, मैंने रूट के स्वामित्व वाली एक फ़ाइल बनाई:

echo foo | sudo tee fff

और फिर फ़ाइल को vimउस तरीके से संपादित करने के लिए आगे बढ़े जिस तरीके से आप वर्णन करते हैं, लेकिन straceजो हो रहा है उसे देखने के लिए प्रक्रिया संलग्न करें :

strace vim fff 2> strace.out

मैंने तब जाँच की strace.outऔर पाया:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

तो, फ़ाइल को पहले हटा दिया गया था ( unlink("fff")), फिर उसी नाम की एक नई फ़ाइल बनाई गई थी ( open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)) और मेरे द्वारा किए गए संशोधनों को लिखा गया था ( write(4, "foasdasdao\n", 11))। यदि आप इसे घर पर आज़माते हैं, तो आप देखेंगे कि आपके द्वारा इसे संपादित करने के बाद vim, फ़ाइल अब आपके पास होगी और रूट नहीं होगी।

इसलिए, सख्ती से बोलना, vimऐसी फाइल को संपादित नहीं करना है जिसकी आपके पास कोई पहुंच नहीं है। यह एक डायरेक्टरी से एक फाइल को डिलीट कर रहा है, जिस पर आपके पास राइट एक्सेस है और फिर एक नई फाइल बनाने के लिए, फिर से, आपके पास राइट एक्सेस है।



8
@CCJ यह डायरेक्ट्री पर राइट ऑपरेशन है, लेकिन फाइल नहीं। फ़ाइलों पर कार्रवाई लिखना वे हैं जो फ़ाइल की सामग्री को बदलते हैं। जब आप इसकी सामग्री बदल रहे हैं, उसी टोकन द्वारा, फ़ाइलें बनाना / हटाना निर्देशिका पर कार्रवाई लिखना है।
terdon

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

5
@PeterCordes उम, ठीक है। यद्यपि आप अपनी शिकायतों को विम डेवलपर्स को निर्देशित करना चाहते हैं। मैं भी इस चीज़ का उपयोग नहीं करता, मैं emacs शिविर में हूँ।
terdon

3
@CCJ किसी फ़ाइल को हटाना निर्देशिका को लिखने का कार्य है, न कि फ़ाइल में। यह पूरी तरह से सहज है कि यदि आप एक निर्देशिका के प्रभारी हैं (यानी, इस पर पहुंच लिखें), तो आपको यह नियंत्रित करने में सक्षम होना चाहिए कि इसमें क्या है, और एक व्यक्तिगत फ़ाइल के स्वामी को आपको ओवरराइड करने की अनुमति नहीं दी जानी चाहिए।
fkraiem

16

जब तक आप मूल निर्देशिका के मालिक हैं, आप हटा सकते हैं या फ़ाइल को बदल सकते हैं, तो अनुमति के बिना कोई फर्क नहीं पड़ता क्योंकि आप निर्देशिका की सामग्री को बदल सकते हैं :)।

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

इसके अलावा:

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


7
ऐसा लगता है कि वीआईएम कई रणनीतियों से चुनता है, जिसमें फिर से लिखना या एक नई फाइल को अनलिंक करना + लिखना शामिल है।
पीटर कॉर्ड्स

3
@PeterCordes हाँ यह स्पष्ट रूप से बहुत मुश्किल करने की कोशिश करेगा कि आप इसे क्या कहते हैं :) बहुत चालाक। :)
रोब

16

उपयोग करने से w!आप मूल फ़ाइल ( जिसे आपको करने की अनुमति है ) निकाल रहे हैं और इसके बजाय अपना संस्करण लिख रहे हैं

जब आपके पास किसी डायरेक्टरी तक पहुंच होती है, तो आप उस डायरेक्टरी के भीतर फाइल बना सकते हैं, ले जा सकते हैं या हटा सकते हैं।

$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file 
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file

अब मुझे अपना यूजर स्विच करना है और फाइल को बदलना है

$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file

अब देखें कि वहां क्या है:

$ cat foo/file
bye

10

देखें :help write-readonly:

                                                        write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

चूंकि आपके पास निर्देशिका पर अनुमतियाँ हैं (मतलब आप इसमें फ़ाइलें बना सकते हैं, हटा सकते हैं या नाम बदल सकते हैं), सिस्टम इसकी अनुमति देता है।


डिफ़ॉल्ट मान में cpoptionsनहीं है W:

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global

2

यह आपके लिए VIM की चेतावनी है जो UNIX में अनुमतियों के काम करने पर विचार करना अपेक्षाकृत महत्वपूर्ण हो सकता है। इस के स्पष्ट unintuitiveness क्योंकि UNIX filesystems फ़ाइल के i-नोड में संग्रहीत फ़ाइल के लिए अनुमति है। निर्देशिका संरचना किसी तरह अलग है और केवल इन i-nodes को लिंक कर रही है। निर्देशिकाएँ में उनकी अनुमतियाँ भी हैं जो कहती हैं कि क्या आप इसमें फ़ाइलों को लिंक / अनलिंक कर सकते हैं, या इसे पढ़ सकते हैं या उप-निर्देशिकाओं में ले जा सकते हैं। यह डिज़ाइन यह अनुमति देता है कि एक ही फ़ाइल निर्देशिका संरचना (हार्ड लिंक के माध्यम से) में कई अलग-अलग स्थानों पर दिखाई दे सकती है। "ऐड! ओवरराइड" कहने से VIM आपको चेतावनी देने की कोशिश कर रहा है कि मूल फ़ाइल को अनलिंक किया जाएगा (इसलिए यह सभी अन्य स्थानों पर अछूता रहेगा) और नई फ़ाइल बनाई जाएगी और निर्देशिका संरचना में मूल स्थान से जुड़ी होगी। ऐसी स्थिति में जब मूल फ़ाइल की लिंक-गणना शून्य हो जाती है, तो मूल फ़ाइल को मुक्त कर दिया जाएगा, लेकिन यदि नहीं, तो आप प्रभावी रूप से फ़ाइल को क्लोन कर रहे हैं। फ़ाइल को खोलना भी लिंक के रूप में गिना जाता है, इसलिए यदि कुछ प्रोग्राम ने फ़ाइल को खोला और आप "जोड़ने! ओवरराइड करने" के लिए सहमत हैं, तो प्रोग्राम आपके द्वारा VIM के साथ फ़ाइल में किए गए परिवर्तनों को नहीं देखेगा। फ़ाइल केवल VIM द्वारा निर्देशिका से अनलिंक हो जाती है और फ़ाइल को किसी अन्य प्रोग्राम द्वारा बंद करने के बाद, फ़ाइल मुक्त हो जाएगी, जब तक कि इसे कहीं और लिंक नहीं किया जाता।

कृपया ध्यान दें कि विंडोज़ में, फ़ाइलों के लिए अनुमतियाँ निर्देशिका में संग्रहीत की जाती हैं, इसलिए विंडोज अनुमतियों के दृष्टिकोण से, यह दृश्य व्यवहार वास्तव में अजीब लग सकता है। फ़ाइल में लिखने के लिए, Windows तार्किक रूप से कुछ निर्देशिका अनुमतियों, यहां तक ​​कि सुपर-निर्देशिका अनुमतियों की भी जाँच कर सकता है। जैसा कि ऊपर कहा गया है, UNIX में, निर्देशिका अनुमतियाँ फ़ाइल के साथ छेड़छाड़ के लिए अप्रासंगिक हैं जहाँ तक आप इसे सूचीबद्ध करने और इसे खोलने में सक्षम थे (यानी सभी सुपर-निर्देशिका के लिए x थे)। UNIX में खोली गई फ़ाइल में फ़ाइल नाम भी नहीं हो सकता है अगर इसे खोलने के बाद सभी निर्देशिकाओं से अनलिंक किया गया था।

उदाहरण के लिए, आपके पास फ़ाइल / होम / user1 / foo है और यह (यानी हार्डलिंकड टू / होम / user2 / foo) के रूप में एक ही फाइल है और यह फाइल किसी के द्वारा भी लिखने योग्य नहीं है और वर्तमान में प्रोग्राम P (ओपन रीड-राइट) द्वारा खोला गया है कार्यक्रम रूट द्वारा शुरू किया गया)। यदि user1 इसे vim और overwrites के साथ खोलता है, तो वह अपनी प्रति बनाता है और अब मूल फ़ाइल नहीं देखता है। यदि बाद में उपयोगकर्ता 2 विम के साथ अपना लिंक खोलता है और इसमें लिखता है, तो यह फिर से अनलिंक हो जाएगा और वह एक और कॉपी बनाएगा। प्रोग्राम पी अभी भी मूल फ़ाइल को देखेगा और इसमें स्वतंत्र रूप से पढ़ या लिख ​​सकता है। जैसे ही प्रोग्राम फ़ाइल को बंद करता है, फ़ाइल गायब हो जाएगी (फाइलसिस्टम द्वारा मुक्त हो जाएगी)।


2

आपकी विम एडिटर प्रक्रिया और आपकी फाइल दोनों आपके

 getpwnam("navid")->pw_uid

स्वामित्व ताकि आप भी खोल सकें

 :!chmod +w %

और आप अनुमान लगा सकते हैं कि एक बार और भी सरल

 :!rm %

(केवल + w की आवश्यकता होती है, पर अनुमति रद्द करें और स्वामित्व भी नहीं) टाइप करने के लिए किसी व्यक्ति के लिए बहुत बार-बार हो जाता है ताकि विम स्वचालित रूप से ऑफ़र करने और स्वचालित रूप से इस तरह के ऑपरेशन को करने के लिए अनुरोध किया गया था।

अपनी बड़ी बहन की ओवरराइटिंग का प्रयास करें

 /home/whoopi/.profile

के रूप में केवल नावीद और दांव अपने विम हैं आप अपने वांछित इनकार देता है।


कोड संपादन के लिए @Zanna का शुक्रिया अदा करें, भले ही इससे मुझे प्रतिष्ठा का एक छोटा सा हिस्सा मिल गया हो, इसके लायक है।
रोमन Czyborra

1

यह वास्तव में एक उत्तर नहीं है, लेकिन यदि आप वास्तव में एक फ़ाइल सेट करना चाहते हैं ताकि कोई भी इसे बदल या हटा नहीं सके, तो आप इसे अपरिवर्तनीय बना सकते हैं।

आम तौर पर, यहां तक ​​कि जब कोई फ़ाइल रूट के स्वामित्व में होती है, तब भी आप फ़ाइल को हटा सकते हैं यदि आपके पास फ़ोल्डर के लिए अनुमतियाँ हैं। लेकिन जब आप फ़ाइल को अपरिवर्तनीय बनाते हैं, तो भी रूट इसे संशोधित या हटा नहीं सकता है।

फ़ाइल को अपरिवर्तनीय बनाने के लिए (आपको आवश्यकता है sudo):

sudo chattr +i myFile.txt

आप इसे lsattr( iपरिणाम में पत्र ) के साथ देख सकते हैं :

$ lsattr myFile.txt
----i--------e-- myFile.txt

फ़ाइल को फिर से सामान्य बनाने के लिए:

sudo chattr -i myFile.txt

स्पष्ट करने के लिए: जब कोई फ़ाइल अपरिवर्तनीय होती है, तो उसे हटाया नहीं जा सकता है, नाम बदला जा सकता है, संशोधित किया जा सकता है या यहां तक ​​कि हार्ड-लिंक भी किया जा सकता है।

यह पढ़ने लायक है man chattr, क्योंकि फाइलों में कई उपयोगी विशेषताएँ हो सकती हैं।

आपको "प्रतिबंधित विलोपन" भी उपयोगी लग सकता है। यदि किसी फ़ोल्डर (फ़ाइल नहीं) पर रखा जाता है, तो इसका मतलब है कि जो कोई भी फ़ोल्डर में फ़ाइल बनाता है उसे उस फ़ाइल को संशोधित करने या हटाने की अनुमति है, लेकिन कोई अन्य नहीं है (रूट को छोड़कर)। फ़ोल्डर /tmpमें यह ध्वज सेट है। आप इसे tध्वज के साथ देख सकते हैं /tmp:

$ ls -l --directory /tmp
drwxrwxrwt 10 root root 4096 Sep  6 09:00 /tmp

किसी फ़ोल्डर पर प्रतिबंधित विलोपन ध्वज को सेट या हटाने के लिए:

chmod +t myFolder      # Add the restricted deletion flag.
chmod -t myFolder      # Remove the restricted deletion flag.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.