आम कैविट्स
रीड-ओनली फाइल प्रॉब्लम के आस-पास होने का सबसे आम तरीका सुपर-यूजर के रूप में एक कार्यान्वयन के लिए वर्तमान फ़ाइल में एक पाइप खोलना है sudo tee
। हालाँकि, सभी सबसे लोकप्रिय समाधान जो मैंने इंटरनेट के आसपास पाए हैं उनमें कई संभावित कैविटीज़ का संयोजन है:
- पूरी फाइल टर्मिनल पर लिखी जाती है, साथ ही फाइल भी। यह बड़ी फ़ाइलों के लिए धीमा हो सकता है, खासकर धीमे नेटवर्क कनेक्शन पर।
- फ़ाइल अपने मोड और समान विशेषताओं को खो देती है।
- असामान्य वर्ण या रिक्त स्थान वाले फ़ाइल पथ को सही तरीके से नहीं संभाला जा सकता है।
समाधान
इन सभी मुद्दों के बारे में जानने के लिए, आप निम्न कमांड का उपयोग कर सकते हैं:
" On POSIX (Linux/Mac/BSD):
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
" Depending on the implementation, you might need this on Windows:
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >NUL'
इन्हें छोटा किया जा सकता है, सम्मान से:
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'
व्याख्या
:
कमांड शुरू करता है; कमांड में प्रवेश करने के लिए आपको इस चरित्र को सामान्य मोड में टाइप करना होगा। इसे लिपियों में छोड़ दिया जाना चाहिए।
sil[ent]
कमांड से आउटपुट दबाता है। इस मामले में, हम कमांड Press any key to continue
चलाने के बाद दिखाई देने वाले प्रांप्ट को रोकना चाहते हैं :!
।
exec[ute]
कमांड के रूप में एक स्ट्रिंग निष्पादित करता है। हम सिर्फ :write
इसलिए नहीं चल सकते क्योंकि यह आवश्यक फ़ंक्शन कॉल को संसाधित नहीं करेगा।
!
:!
आदेश का प्रतिनिधित्व करता है : एकमात्र आदेश जो :write
स्वीकार करता है। आम तौर पर, :write
एक फ़ाइल पथ को स्वीकार करता है जिस पर लिखना है। :!
अपने दम पर एक शेल में एक कमांड चलाता है (उदाहरण के लिए, का उपयोग करके bash -c
)। इसके साथ :write
, यह शेल में कमांड चलाएगा, और फिर पूरी फाइल को लिखेगा stdin
।
sudo
स्पष्ट होना चाहिए, क्योंकि आप यहाँ हैं। सुपर-उपयोगकर्ता के रूप में कमांड चलाएँ। 'कैसे काम करता है' के बारे में नेट के आसपास बहुत जानकारी है।
tee
stdin
दिए गए फ़ाइल को पाइप । :write
को लिखेंगे stdin
, तब सुपर-उपयोगकर्ता tee
फ़ाइल सामग्री प्राप्त करेगा और फ़ाइल लिखेगा। यह एक नई फ़ाइल नहीं बनाएगा - केवल सामग्री को अधिलेखित कर देगा - इसलिए फ़ाइल मोड और विशेषताओं को संरक्षित किया जाएगा।
shellescape()
वर्तमान शेल के लिए दिए गए फ़ाइल पथ में विशेष वर्ण से बच जाता है। केवल एक पैरामीटर के साथ, यह आमतौर पर आवश्यक के रूप में उद्धरण में पथ संलग्न करेगा। चूंकि हम एक पूर्ण शेल कमांड लाइन पर भेज रहे हैं, इसलिए हम दूसरे विशेष वर्णों से बचने के लिए एक गैर-शून्य मान पास करना चाहेंगे जो अन्य विशेष वर्णों से बचने के लिए सक्षम हो सकता है जो अन्यथा शेल तक यात्रा कर सकते हैं।
@%
%
रजिस्टर की सामग्री को पढ़ता है , जिसमें वर्तमान बफ़र फ़ाइल नाम है। यह जरूरी नहीं कि एक पूर्ण मार्ग है, इसलिए सुनिश्चित करें कि आपने वर्तमान निर्देशिका को नहीं बदला है। कुछ समाधानों में, आप वाणिज्यिक-चिन्ह को छोड़ देंगे। स्थान के आधार पर, %
एक मान्य अभिव्यक्ति है, और %
रजिस्टर को पढ़ने के समान प्रभाव है । एक और अभिव्यक्ति के अंदर निहित शॉर्टकट को आमतौर पर अस्वीकृत कर दिया जाता है, हालांकि: जैसे कि इस मामले में।
>NUL
और मंच के अशक्त डिवाइस पर >/dev/null
पुनर्निर्देशित stdout
। भले ही हमने कमांड को चुप करा दिया है, हम नहीं चाहते हैं कि ओवरहेड पाइपिंग से जुड़े सभी ओवरहेड stdin
वापस जाएं - इसे जितनी जल्दी हो सके डंप करें। NUL
डॉस, MS-DOS, और विंडोज पर शून्य डिवाइस है, एक वैध फ़ाइल नहीं है। NUL में Windows 8 के पुनर्निर्देशन के परिणामस्वरूप NUL नामक फाइल में नहीं लिखा जाता है। NUL नाम के अपने डेस्कटॉप पर एक फ़ाइल बनाने की कोशिश करें, जो एक फ़ाइल एक्सटेंशन के साथ या उसके बिना है: आप ऐसा करने में असमर्थ होंगे। (विंडोज में कई अन्य डिवाइस के नाम हैं जो जानने लायक हो सकते हैं।)
~ / .Vimrc
प्लेटफार्म पर निर्भर
बेशक, आप अभी भी उन लोगों को याद नहीं करना चाहते हैं और उन्हें हर बार टाइप करते हैं। एक सरल उपयोगकर्ता कमांड के लिए उपयुक्त कमांड को मैप करना बहुत आसान है। POSIX पर ऐसा करने के लिए, आप अपनी ~/.vimrc
फ़ाइल में निम्न पंक्ति जोड़ सकते हैं , अगर यह पहले से मौजूद नहीं है, तो इसे बनाएं:
command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
यह आपको सुपर-उपयोगकर्ता अनुमतियों के साथ वर्तमान फ़ाइल लिखने के लिए W (केस-संवेदी) कमांड टाइप करने की अनुमति देगा - बहुत आसान।
स्वतंत्र मंच
मैं एक प्लेटफ़ॉर्म-स्वतंत्र ~/.vimrc
फ़ाइल का उपयोग करता हूं जो कंप्यूटरों में सिंक्रनाइज़ होती है, इसलिए मैंने मल्टी-प्लेटफ़ॉर्म कार्यक्षमता को खान में जोड़ा। यहाँ ~/.vimrc
केवल प्रासंगिक सेटिंग्स के साथ है:
#!vim
" Use za (not a command; the keys) in normal mode to toggle a fold.
" META_COMMENT Modeline Definition: {{{1
" vim: ts=4 sw=4 sr sts=4 fdm=marker ff=unix fenc=utf-8
" ts: Actual tab character stops.
" sw: Indentation commands shift by this much.
" sr: Round existing indentation when using shift commands.
" sts: Virtual tab stops while using tab key.
" fdm: Folds are manually defined in file syntax.
" ff: Line endings should always be <NL> (line feed #09).
" fenc: Should always be UTF-8; #! must be first bytes, so no BOM.
" General Commands: User Ex commands. {{{1
command W call WriteAsSuperUser(@%) " Write file as super-user.
" Helper Functions: Used by user Ex commands. {{{1
function GetNullDevice() " Gets the path to the null device. {{{2
if filewritable('/dev/null')
return '/dev/null'
else
return 'NUL'
endif
endfunction
function WriteAsSuperUser(file) " Write buffer to a:file as the super user (on POSIX, root). {{{2
exec '%write !sudo tee ' . shellescape(a:file, 1) . ' >' . GetNullDevice()
endfunction
" }}}1
" EOF