Vi içindeki bir dosyada root izinleri alınıyor mu? [kapalı]


245

Genellikle yapılandırma dosyalarını düzenlerken vi ile bir tane açacağım ve sonra kaydetmeye gittiğimde, yazmadığımı fark ettim

sudo vi filename

Dosyayı kaydetmek için vi sudo yetkileri vermenin herhangi bir yolu var mı? Bir süre önce vi hakkında bazı şeyler ararken bu konuda bir şeyler gördüğümü hatırlıyorum, ama şimdi bulamıyorum.


belki sadece bir kopyasını ana dizininize kaydedin ve daha sonra "sudo mv"
paan

Yanıtlar:


296

% geçerli dosya adıyla değiştirilir, böylece şunları kullanabilirsiniz:

:w !sudo tee %

( vimdosyanın değiştirildiğini algılar ve yeniden yüklenmesini isteyip istemediğinizi sorar. [L]Tamam yerine seçerek evet deyin .)

Kısayol olarak kendi komutunuzu tanımlayabilirsiniz. Şunlara aşağıdakileri ekleyin .vimrc:

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

Yukarıdakileri kullanarak :W<Enter>dosyayı kaydetmek için yazabilirsiniz . Bunu yazdığımdan beri, bunu yapmak için daha güzel bir yol buldum:

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

Bu şekilde yazabilirsiniz :w!!ve imleci sonunda bırakarak tam komut satırına genişletilir, böylece isterseniz %kendi dosya adınızla değiştirebilirsiniz .


5
Bu gvim'de çalışıyor mu? Komutun çalıştırılması Vim'in parola sormasına neden olur, ancak girişi kabul etmez. Sonunda iki denemede zaman aşımına sudo: 1 incorrect password attempt
uğrar

gvim farklı davranmak için hiçbir neden görmezdim ... tek başına sudo doğru çalışır emin misiniz?

Yeni bir dosyayı kaydetmek için kök ayrıcalıklarına ihtiyacınız varsa,% değerini yeni dosyanın adıyla (yol dahil) değiştirin.
gvkv

Bazen, kullanıcılarınızı önce sudoer dosyasına eklemeniz, kök kullanıcıyı girmeniz ve /etc/sudoersdosyayı açmanız your_username ALL=(ALL) ALL, satırın altına eklemeniz root ALL=(ALL) ALL, çıkmanız ve kaydetmeniz gerekir.
11:18

1
@coolesting: 1) yapmanız gereken yaklaşık bin şey daha var… hepsini listeleyemeyiz. 2) her zaman kullanmalısınız visudo.

32

Genel olarak vi işleminin etkin kullanıcı kimliğini değiştiremezsiniz, ancak bunu yapabilirsiniz:

:w !sudo tee myfile

1
:w !sudo tee % >/dev/nullveya :w !sudo dd of=%dosya kaydedilirken dosyanın içeriğinin yankılanmasını önleyin.
jamessan

Bunun nasıl çalıştığını açıklayabilir misiniz? Başladım teeve bunun bir Unix boru komutu olduğunu gördüm ve !bir kabuk komutu ekledi. Mi :wtarafından taşınıyor alır standart dışı, yazma tee?
Eric Hu

4
@Eric, doğru. "tee myfile" komutu stdin'i myfile'a kopyalar. "sudo tee myfile" komutunu çalıştırmak aynı şeyi yapar, ancak tee işlemi root'a ait olduğu için myfile benzer şekilde root'a ait olacaktır. Vi tarafında ": w! Bazı komut satırı" tüm satırları "bazı komut satırına" bağlar.
Mark Harrison

16

Ortak Uyarılar

Salt okunur dosya sorununun üstesinden gelmek için en yaygın yöntem, bir uygulama kullanarak süper kullanıcı olarak geçerli dosyaya bir boru açmaktır sudo tee. Ancak, internette bulduğum en popüler çözümlerin hepsinin birkaç potansiyel uyarının bir kombinasyonu var:

  • Tüm dosya terminale ve dosyaya yazılır. Büyük dosyalar için, özellikle yavaş ağ bağlantıları üzerinden bu yavaş olabilir.
  • Dosya, modlarını ve benzer niteliklerini kaybeder.
  • Alışılmadık karakterleri veya boşlukları olan dosya yolları düzgün işlenmeyebilir.

Çözümler

Tüm bu sorunların üstesinden gelmek için aşağıdaki komutu kullanabilirsiniz:

" 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'

Bunlar saygıyla kısaltılabilir:

:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'

açıklama

:komutu başlatır; bir komut girmeye başlamak için bu karakteri normal modda yazmanız gerekir. Komut dosyalarında atlanmalıdır.

sil[ent]komuttan çıktıları bastırır. Bu durumda, komutu Press any key to continueçalıştırdıktan sonra görünen -like istemini durdurmak istiyoruz :!.

exec[ute]bir dizeyi komut olarak yürütür. Biz sadece koşamam :writegerekli işlev çağrısını işlemez çünkü.

!:!komutu temsil eder : :writekabul eden tek komut . Normalde, :writeyazılacak dosya yolunu kabul eder. :!kendi başına bir kabukta bir komut çalıştırır (örneğin, kullanarak bash -c). İle :write, komutu kabukta çalıştırır ve ardından tüm dosyayı adresine yazar stdin.

sudoaçık olmalısın, çünkü bu yüzden buradasın. Süper kullanıcı olarak komutu çalıştırın. Ağın etrafında bunun nasıl çalıştığı hakkında bol miktarda bilgi var.

teeBorular stdinverilen dosyaya. :writeyazacağına stdin, daha sonra süper kullanıcı teedosya içeriğini almak ve dosyasına yazacaktır. Yeni bir dosya oluşturmaz - sadece içeriğin üzerine yaz - böylece dosya modları ve öznitelikleri korunur.

shellescape()geçerli kabuk için uygun şekilde verilen dosya yolundaki özel karakterlerden kaçar. Sadece bir parametreyle, yolu gerektiğinde tırnak içine alır. Tam bir kabuk komut satırına gönderdiğimiz için, aksi takdirde kabuktan çıkabilen diğer özel karakterlerin ters eğik çizgiden kaçmasını sağlamak için ikinci argüman olarak sıfırdan farklı bir değer geçirmek isteyeceğiz.

@%%geçerli arabellek dosya adını içeren kaydın içeriğini okur . Mutlak bir yol olması gerekmez, bu nedenle geçerli dizini değiştirmediğinizden emin olun. Bazı çözümlerde, reklamdaki simgesi atlanır. Konuma bağlı olarak, %geçerli bir ifadedir ve %kaydı okumakla aynı etkiye sahiptir . Bununla birlikte, başka bir ifadenin içine yerleştirilmiş olan kısayol genellikle izin verilmez: bu durumda olduğu gibi.

>NULve platformun boş cihazına >/dev/nullyönlendirin stdout. Komutu susturmuş olsak da, boru ile ilişkili tüm ek yükün vim'e stdingeri dönmesini istemiyoruz - en iyisi mümkün olduğunca erken dökmek. NULDOS, MS-DOS ve Windows'daki null aygıt, geçerli bir dosya değil. Windows 8'den itibaren NUL'a yeniden yönlendirme, NUL adında bir dosyanın yazılmasına neden olmaz. Masaüstünüzde NUL adında bir dosya uzantısı olsun veya olmasın bir dosya oluşturmayı deneyin: bunu yapamazsınız. (Windows'da öğrenmeye değer diğer birkaç cihaz adı vardır.)

~ / .Vimrc

Platform-Bağımlı

Tabii ki, hala bunları ezberlemek ve her seferinde yazmak istemiyorsunuz. Uygun komutu daha basit bir kullanıcı komutuyla eşleştirmek çok daha kolaydır. POSIX'te bunu yapmak için, ~/.vimrcdosyanıza şu satırı ekleyerek mevcut satırı oluşturabilirsiniz:

command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

Bu, geçerli dosyayı süper kullanıcı izinleriyle yazmak için W (büyük / küçük harfe duyarlı) komutunu yazmanıza olanak tanır - çok daha kolay.

Platform bağımsız

~/.vimrcBilgisayarlar arasında eşitlenen platformdan bağımsız bir dosya kullanıyorum, bu yüzden benimkine çoklu platform işlevselliği ekledim. Aşağıda ~/.vimrcyalnızca ilgili ayarların bulunduğu bir:

#!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

Ya aslında C: \ dev \ null dizininde bir dünya yazılabilir dosyası oluşturarak Windows'u açarsanız?
Paul Stelian

1
@PaulStelian Mümkün, ancak olası değil. Çeşitli platformları ve koşulları hesaba katmak için bu kodu kolayca genişletebilirsiniz. Gerçekte, Windows'da sudovar olan ancak olmayan bir durumla karşılaşmanız olası değildir /dev/null, bu nedenle gerçek çapraz platform desteği istiyorsanız daha meraklı olmanız gerekir. Daha çok bir giriş - düşünce için yiyecek. :)
Zenexer

11

Vim kullanıyorsanız , sudo.vim adında bir komut dosyası vardır . Okumak için kök erişimine ihtiyacınız olan bir dosyayı açtığınızı fark ederseniz,

: e sudo:%
Vim,% öğesini geçerli dosyanın adıyla değiştirir ve sudo:sudo.vim komut dosyasına okuma ve yazma için yönetimi devralmasını bildirir.


4
Kaçan dosya adlarıyla uygun önlemleri almadığı için bu komut dosyasını kullanmanızı önermem.
jamessan

7

Ryan'ın tavsiyesi genellikle iyidir, ancak 3. adımı uygularsanız geçici dosyayı taşımayın; yanlış sahiplik ve izinlere sahip olacak. Bunun yerine, sudoeditdoğru dosyayı ve :rgeçici dosyanın içeriğini ( veya benzerlerini kullanarak) okuyun .

Adım 2'yi takip ediyorsanız :w!, dosyayı yazmaya zorlamak için kullanın .


3

Düzenlemek için sudo erişimine ihtiyacınız olan bir dosyada ekleme moduna geçtiğinizde,

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

Bunu özlersem, genellikle

:w ~/edited_blah.tmp
:q

..sonra..

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

..veya..

sudo mv edited_blah.tmp /etc/blah

Muhtemelen bunu yapmanın daha az dolambaçlı bir yolu var, ama işe yarıyor.


cat $ tmp> $ target yaratıcıdır, ancak dosyayı sadece sudo mv yapmamak için herhangi bir neden var mı?
ojrac

İyi bir nokta .. Ayrıca sudo kedi ile büyük bir sorun vardı> / etc / blah - sudo dosyayı cat için kullanır, daha sonra düzenli kullanıcı / etc / blah (hangi işe yaramaz) yazmak için .. Düzeltildi cevap ve daha iyi sudo mv öneri ekledi ..
dbr

MV önerisi izinleri korumaz.
Paul Stelian

1

Hızlı bir Google bu tavsiyeyi veriyor gibi görünüyor:

  1. Salt okunursa düzenlemeyi denemeyin.
  2. Dosyadaki izinleri değiştirebilirsiniz. (Tasarruf etmenize izin verip vermeyeceğiniz deneme amaçlıdır.)
  3. Yine de düzenlediyseniz, geçici bir dosyaya kaydedin ve taşıyın.

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



0

Bu ~ / .bashrc içinde var:

alias svim='sudo vim'

Şimdi bir yapılandırma dosyasını düzenlemem gerektiğinde sadece svim ile açıyorum.


2
sudoeditO root olarak çalışan vim gerektirmediğinden komut tercih edilmelidir.
jamessan

2
Bu hala OP'nin kaçtığı svim yerine vim bağlamanızı engellemez.
ScaryAardvark

3
-1, Bu sadece "bir dosyayı açarken sudo yazmayı unutmayın" diyor, OP vi içinde kök ayrıcalıklarını nasıl alabileceklerini bilmek istiyor.
Brad Koch

-2

Göz önünde bulundurabileceğiniz hızlı bir kesmek, düzenlediğiniz dosyada bir chmod yapmak, vim ile kaydetmek ve daha sonra dosyanın orijinaline geri dönmektir.

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)

Elbette bu yaklaşımı güvenlik konusunda endişelendiğiniz bir sistemde önermiyorum, çünkü birkaç saniye boyunca herkes farkında olmadan dosyayı okuyabilir / değiştirebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.