Vi के अंदर फ़ाइल पर रूट अनुमतियां प्राप्त करना [बन्द है]


245

कॉन्फ़िगर फ़ाइलों को संपादित करते समय, मैं vi के साथ एक को खोलूंगा और फिर जब मैं इसे सहेजने जाऊंगा तो मुझे एहसास होगा कि मैंने टाइप नहीं किया

sudo vi filename

क्या फ़ाइल को सहेजने के लिए vi sudo विशेषाधिकार देने का कोई तरीका है? मुझे लगता है कि कुछ समय पहले vi के बारे में कुछ सामान ढूंढते हुए इस बारे में कुछ याद आता है, लेकिन अब मुझे यह नहीं मिल रहा है।


हो सकता है कि अपने होम डायरेक्टरी और "सुडो एमवी" में बाद में एक कॉपी बचा लें
पान

जवाबों:


296

% वर्तमान फ़ाइल नाम से बदल दिया गया है, इस प्रकार आप उपयोग कर सकते हैं:

:w !sudo tee %

( vimयह पता लगाएगा कि फ़ाइल बदल दी गई है और पूछें कि क्या आप इसे फिर से लोड करना चाहते हैं। [L]ठीक है के बजाय चुनने के द्वारा हाँ कहें ।)

शॉर्टकट के रूप में, आप अपनी खुद की कमांड को परिभाषित कर सकते हैं। निम्नलिखित को अपने में रखें .vimrc:

command W w !sudo tee % >/dev/null

ऊपर के साथ आप :W<Enter>फाइल को सेव करने के लिए टाइप कर सकते हैं । जब से मैंने यह लिखा है, मैंने ऐसा करने के लिए एक अच्छा तरीका (मेरी राय में) पाया है:

cmap w!! w !sudo tee >/dev/null %

इस तरह से आप टाइप कर सकते हैं :w!!और कर्सर को अंत में छोड़ते हुए इसे पूरी कमांड लाइन में विस्तारित किया जाएगा, ताकि आप चाहें तो %अपनी खुद की एक फ़ाइल नाम के साथ बदल सकते हैं।


5
क्या यह gvim में काम करता है? कमांड चलाने से Vim पासवर्ड के लिए संकेत देता है लेकिन इनपुट स्वीकार नहीं करता है। यह अंततः दो प्रयासों पर निकलता है और कहता है:sudo: 1 incorrect password attempt
cmcginty

मैं अलग तरह से व्यवहार करने के लिए gvim का कोई कारण नहीं देखूंगा ... क्या आपको यकीन है कि sudo अपने आप सही तरीके से काम करता है?

यदि आपको नई फ़ाइल सहेजने के लिए रूट विशेषाधिकारों की आवश्यकता है, तो नई फ़ाइल के नाम (पथ सहित) के साथ% बदलें।
gvkv

कुछ समय के लिए, आपको अपने उपयोगकर्ता को पहले sudoer फ़ाइल में जोड़ने की आवश्यकता है, रूट उपयोगकर्ता दर्ज करें और /etc/sudoersफ़ाइल खोलें , your_username ALL=(ALL) ALLलाइन के नीचे जोड़ें root ALL=(ALL) ALL, छोड़ें और सहेजें।
शीतलक

1
@ कूलिंग: 1) एक हजार अन्य चीजें हैं जो आपको करने की आवश्यकता है ... हम उन सभी को सूचीबद्ध नहीं कर सकते। 2) आपको हमेशा उपयोग करना चाहिए visudo

32

सामान्य तौर पर, आप vi प्रक्रिया की प्रभावी उपयोगकर्ता आईडी नहीं बदल सकते, लेकिन आप ऐसा कर सकते हैं:

:w !sudo tee myfile

1
:w !sudo tee % >/dev/nullया :w !sudo dd of=%फ़ाइल सहेजने के बाद फ़ाइल की सामग्री वापस गूँजने से बचें।
जामसेन

क्या आप बता सकते हैं कि यह कैसे काम करता है? मैंने ऊपर देखा teeऔर यह एक यूनिक्स पाइप कमांड है, और !एक शेल कमांड सम्मिलित करता है। क्या :wलेखन मानक से बाहर है, जो पाइप हो जाता है tee?
एरिक हू

4
@ एरिक, यह सही है। कमांड "टी माईफाइल", स्टीन की नकल मायफाइल में करेगा। "sudo tee myfile" को चलाने से भी ऐसा ही होगा, लेकिन जब से tee प्रक्रिया का स्वामित्व होता है, तब तक myfile का स्वामित्व जड़ से होगा। Vi साइड पर, ": w! कुछ कमांड लाइन" सभी लाइनों को "कुछ कमांड लाइन" में पाइप करेगा।
मार्क हैरिसन

16

आम कैविट्स

रीड-ओनली फाइल प्रॉब्लम के आस-पास होने का सबसे आम तरीका सुपर-यूजर के रूप में एक कार्यान्वयन के लिए वर्तमान फ़ाइल में एक पाइप खोलना है 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स्पष्ट होना चाहिए, क्योंकि आप यहाँ हैं। सुपर-उपयोगकर्ता के रूप में कमांड चलाएँ। 'कैसे काम करता है' के बारे में नेट के आसपास बहुत जानकारी है।

teestdinदिए गए फ़ाइल को पाइप । :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

क्या होगा अगर आप वास्तव में C: \ dev \ n पर एक विश्व लिखने योग्य फ़ाइल बनाकर Windows यात्रा करते हैं?
पॉल स्टेलियन

1
@PaulStelian संभव है, लेकिन संभावना नहीं है। आप विभिन्न प्लेटफार्मों और परिस्थितियों के लिए इस कोड को आसानी से बढ़ा सकते हैं। वास्तव में, आप विंडोज पर एक ऐसी स्थिति का सामना करने की संभावना नहीं रखते हैं जहां sudoमौजूद है, लेकिन /dev/nullऐसा नहीं है , इसलिए यदि आपको सच्चा क्रॉस-प्लेटफ़ॉर्म समर्थन चाहिए, तो आपको कट्टरपंथी होने की आवश्यकता होगी। यह एक परिचय से अधिक है - विचार के लिए भोजन। :)
ज़ेनेक्सर

11

यदि आप विम का उपयोग कर रहे हैं , तो sudo.vim नामक एक स्क्रिप्ट उपलब्ध है । यदि आप पाते हैं कि आपने एक फ़ाइल खोली है जिसे पढ़ने के लिए आपको रूट एक्सेस की आवश्यकता है, तो टाइप करें

: ई सुदो:%
विम वर्तमान फ़ाइल के नाम के साथ% की जगह लेता है, और sudo:पढ़ने के लिए और लिखने के लिए sudo.vim स्क्रिप्ट को संभालने का निर्देश देता है।


4
मैं इस स्क्रिप्ट का उपयोग करने की सिफारिश नहीं करूंगा क्योंकि यह फिल्नेस से बचने के साथ उचित सावधानी नहीं रखता है।
जैमेसन

7

रयान की सलाह आम तौर पर अच्छी है, हालांकि, यदि चरण 3 का पालन किया जाता है, तो अस्थायी फ़ाइल को स्थानांतरित न करें; इसके पास गलत स्वामित्व और अनुमतियां होंगी। इसके बजाय, sudoeditसही फ़ाइल और :rअस्थायी फ़ाइल की सामग्री (उपयोग या पसंद) में पढ़ें ।

यदि चरण 2 का अनुसरण किया जाता है, :w!तो फ़ाइल को लिखने के लिए बाध्य करने के लिए उपयोग करें।


3

जब आप किसी फाइल पर इन्सर्ट मोड में जाते हैं तो आपको एडिट करने के लिए sudo एक्सेस की आवश्यकता होती है, आपको एक स्टेटस मैसेज मिलता है

-- INSERT -- W10: Warning: Changing a readonly file

अगर मुझे वह याद आती है, तो आमतौर पर मैं करता हूं

:w ~/edited_blah.tmp
:q

..फिर..

sudo "cat edited_blah.tmp > /etc/blah"

..or ..

sudo mv edited_blah.tmp /etc/blah

वहाँ शायद यह करने के लिए एक कम गोल चक्कर रास्ता है, लेकिन यह काम करता है।


बिल्ली $ tmp> $ लक्ष्य रचनात्मक है, लेकिन क्या कोई कारण सिर्फ sudo mv फ़ाइल नहीं है?
ओज्रेक

अच्छी बात है .. वहाँ भी sudo cat के साथ एक बड़ी समस्या थी कुछ /> / etc / blah - जो sudo का उपयोग फाइल को कैट करने के लिए करेगी, फिर नियमित उपयोगकर्ता को / etc / blah (जो अभ्यस्त कार्य) को लिखने के लिए .. इसमें फिक्स्ड जवाब, और अपने बेहतर sudo mv सुझाव को जोड़ा ..
dbr

एमवी सुझाव अनुमतियों को संरक्षित नहीं करता है।
पॉल स्टेलियन

1

एक त्वरित Google यह सलाह देता है:

  1. अगर यह केवल पढ़ने के लिए संपादित करने का प्रयास न करें।
  2. आप फ़ाइल पर अनुमतियों को बदलने में सक्षम हो सकते हैं। (चाहे वह आपको बचाने के लिए प्रयोग करने पर निर्भर हो या नहीं)
  3. यदि आप अभी भी किसी भी तरह से संपादित करते हैं, तो एक अस्थायी फ़ाइल में सहेजें और फिर इसे स्थानांतरित करें।

http://ubuntuforums.org/showthread.php?t=782136


1

इस प्रश्न का उत्तर दिए जाने के बाद से एक अन्य व्यक्ति सामने आया है, जो सूडोएडिट नामक एक प्लगइन है जो सूडो रीड और सूड्रोवाइट फ़ंक्शन प्रदान करता है, जो डिफ़ॉल्ट रूप से सूडो का उपयोग करने की कोशिश करेगा यदि पहले विफल हो जाता है: http://www.vim.org/cripts/ script.php? SCRIPT_ID = 2709


0

मेरे पास यह मेरी ~ / .bashrc:

alias svim='sudo vim'

अब जब भी मुझे एक config फाइल को संपादित करने की आवश्यकता होती है मैं इसे svim के साथ खोल देता हूं।


2
sudoeditआदेश प्राथमिकता दी जानी चाहिए, क्योंकि यह रूट के रूप में चल रहा है vim आवश्यकता नहीं है।
जामसेन

2
यह अभी भी आप svim के बजाय विम को बांधने से नहीं रोकता है जो कि ओपी को मिला है।
स्केयरअर्डवार्क

3
-1, यह सिर्फ "एक फ़ाइल खोलने पर sudo टाइप करने के लिए याद रखें" कह रहा है, ओपी जानना चाहता है कि वे vi के अंदर रूट विशेषाधिकार कैसे प्राप्त कर सकते हैं।
ब्रैड कोच

-2

आप जिस त्वरित हैक पर विचार कर सकते हैं, आप जिस फ़ाइल का संपादन कर रहे हैं, उस पर एक chmod कर रहे हैं, vim के साथ सेव करें, और फिर फ़ाइल को मूल रूप से जो काम करते हैं, उस पर वापस जाएं।

ls -l test.file (to see the permissions of the file)
chmod 777 test.file
[This is where you save in vim]
chmod xxx test.file (restore the permissions you found in the first step)

निश्चित रूप से मैं इस दृष्टिकोण को ऐसी प्रणाली में अनुशंसित नहीं करता जहां आप सुरक्षा के बारे में चिंतित हैं, क्योंकि कुछ सेकंड के लिए कोई भी आपको बिना एहसास किए फ़ाइल को पढ़ / बदल सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.