vi内のファイルに対するroot権限を取得していますか?[閉まっている]


245

多くの場合、設定ファイルの編集中に、viでファイルを開き、保存しようとすると、入力しなかったことがわかります

sudo vi filename

ファイルを保存するためにvi sudo特権を与える方法はありますか?少し前にviについて調べているときに、これについて何かを見たのを覚えているようですが、今は見つかりません。


多分ちょうどあなたのホームディレクトリにコピーを保存し、後でそれを「sudo mv」
paan

回答:


296

% は現在のファイル名に置き換えられるため、以下を使用できます。

:w !sudo tee %

vimは、ファイルが変更されたことを検出し、再ロードするかどうかを尋ねます[L]。OKではなく選択して、はいと言ってください。)

ショートカットとして、独自のコマンドを定義できます。以下をあなたの中に入れてください.vimrc

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

上記を使用:W<Enter>して、ファイルを保存するために入力できます。私がこれを書いて以来、私はこれを行うためのより良い方法を(私の意見では)見つけました:

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

このように入力する:w!!と、完全なコマンドラインに展開され、カーソルが最後に残ります。そのため%、必要に応じてを独自のファイル名に置き換えることができます。


5
これはgvimで動作しますか?コマンドを実行すると、Vimはパスワードの入力を要求しますが、入力は受け付けません。それは最終的にタイムアウトに2回の試行でと言う:sudo: 1 incorrect password attempt
cmcginty

gvimが異なる動作をする理由はわかりません...確かにsudo自体が正しく動作しますか?

新しいファイルを保存するためにroot権限が必要な場合は、%を新しいファイルの名前(パスを含む)に置き換えます。
gvkv

場合によっては、最初にユーザーをsudoerファイルに追加し、rootユーザーを入力して/etc/sudoersファイルを開きyour_username ALL=(ALL) ALL、行の下に追加しroot ALL=(ALL) ALL、終了して保存する必要があります。
11年

1
@coolesting:1)あなたがしなければならないことが他に約1000あります...私たちはそれらすべてをリストすることはできません。2)常に使用する必要がありますvisudo

32

一般に、viプロセスの実効ユーザーIDを変更することはできませんが、次のように変更できます。

:w !sudo tee myfile

1
:w !sudo tee % >/dev/nullまたは:w !sudo dd of=%、ファイルの保存時にファイルの内容がエコーバックされないようにします。
jamessan 2009

これがどのように機能するか説明できますか?調べてみるteeと、それがUnixのパイプコマンドであり!、シェルコマンドが挿入されています。:wパイプで送られる標準出力への書き込みteeですか?
Eric Hu

4
@エリック、そうです。"tee myfile"コマンドはstdinをmyfileにコピーします。「sudo tee myfile」を実行しても同じことができますが、teeプロセスはrootが所有しているため、myfileも同様にrootが所有します。vi側では、「:w!some command line」はすべての行を「some command line」にパイプします。
Mark Harrison、

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実行後に表示される-likeプロンプトを停止します:!

exec[ute]文字列をコマンドとして実行します。:write必要な関数呼び出しを処理しないため、実行できません。

!:!コマンドを表します::write受け入れる唯一のコマンド。通常、:write書き込み先のファイルパスを受け入れます。 :!単独でシェルでコマンドを実行します(たとえば、を使用bash -c)。を使用:writeすると、シェルでコマンドが実行され、ファイル全体がに書き込まれstdinます。

sudoそれがあなたがここにいる理由だからです。スーパーユーザーとしてコマンドを実行します。それがどのように機能するかについて、ネットの周りにはたくさんの情報があります。

teestdin指定されたファイルにパイプします。 :writeはに書き込みstdin、スーパーユーザーteeはファイルの内容を受信して​​ファイルに書き込みます。新しいファイルは作成されず、内容が上書きされるだけなので、ファイルモードと属性は保持されます。

shellescape()現在のシェルに応じて、指定されたファイルパス内の特殊文字をエスケープします。パラメータが1つだけの場合、通常は必要に応じてパスを引用符で囲みます。完全なシェルコマンドラインに送信しているので、2番目の引数としてゼロ以外の値を渡して、シェルを作動させる可能性のある他の特殊文字のバックスラッシュエスケープを有効にします。

@%%現在のバッファのファイル名を含むレジスタの内容を読み取ります。これは必ずしも絶対パスではないので、現在のディレクトリを変更していないことを確認してください。一部のソリューションでは、コマーシャルアットシンボルが省略されています。場所に応じて、%は有効な式であり、%レジスタを読み取るのと同じ効果があります。ただし、この場合のように、ショートカットは別の式の中にネストされているため、通常は許可されません。

>NULそして、>/dev/nullリダイレクトstdoutプラットフォームのヌルデバイスへ。コマンドを沈黙させたとしても、stdinvimへのパイピングに関連するすべてのオーバーヘッドを望まない-できるだけ早くそれをダンプするのが最善です。 NULDOS、MS-DOS、Windowsのnullデバイスであり、有効なファイルではありません。Windows 8以降では、NULへのリダイレクトによってNULという名前のファイルが書き込まれることはありません。デスクトップにNULという名前のファイルを作成してみてください。ファイル拡張子は付けても付けなくても、作成できません。(Windowsには、他にも知っておく価値のあるデバイス名がいくつかあります。)

〜/ .vimrc

プラットフォーム依存

もちろん、それらを覚えて、毎回入力する必要はありません。適切なコマンドをより単純なユーザーコマンドにマップする方がはるかに簡単です。POSIXでこれを行うには、次の行を~/.vimrcファイルに追加し、まだ存在しない場合は作成します。

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

これにより、:W(大文字と小文字を区別)コマンドを入力して、現在のファイルをスーパーユーザーのアクセス許可で書き込むことができます-はるかに簡単です。

プラットフォームに依存しない

~/.vimrcコンピューター間で同期するプラットフォームに依存しないファイルを使用するため、マルチプラットフォーム機能をマイニングに追加しました。~/.vimrc関連する設定のみのa は次のとおりです。

#!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 \ nullに作成してWindowsを起動するとどうなるでしょうか。
Paul Stelian 16

1
@PaulStelian可能ですが、そうではありません。このコードを簡単に拡張して、さまざまなプラットフォームや状況に対応できます。実際には、sudo存在するが存在しないWindowsの状況に遭遇する可能性は低い/dev/nullので、真のクロスプラットフォームサポートが必要な場合は、より洗練されたものにする必要があります。それは序論のより多くです-考えのための食物。:)
Zenexer 2016

11

Vimを使用している場合は、sudo.vimという名前のスクリプトが利用可能です。rootアクセスが必要なファイルを開いたことが判明した場合は、次のように入力します。

:e sudo:%
Vimは%を現在のファイルの名前に置き換え、sudo:読み取りと書き込みを引き継ぐようにsudo.vimスクリプトに指示します。


4
このスクリプトは、ファイル名のエスケープに関して適切な予防策を講じていないため、使用をお勧めしません。
jamessan 2009

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"

..または..

sudo mv edited_blah.tmp /etc/blah

おそらく、これを回避する方法はそれほどありませんが、機能します。


cat $ tmp> $ targetはクリエイティブですが、ファイルをsudo mvしないだけの理由はありますか?
ojrac 2008年

良い点.. sudo cat何か> / etc / blahにも大きな問題がありました-これはsudoを使用してファイルをcatし、次に通常のユーザーが/ etc / blahに書き込むようにします(これは機能しません)。答えは、と...あなたのより良いのsudo mvとの提案を追加
DBR

mvの提案では、権限は保持されません。
Paul Stelian 16

1

手っ取り早いGoogleはこの助言を与えるようです:

  1. 読み取り専用の場合は編集しないでください。
  2. ファイルの権限を変更できる場合があります。(保存できるかどうかは実験次第です。)
  3. それでも編集した場合は、一時ファイルに保存してから移動します。

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



0

私の〜/ .bashrcにこれがあります:

alias svim='sudo vim'

設定ファイルを編集する必要があるときはいつでも、svimでそれを開くだけです。


2
sudoeditrootとしてvimを実行する必要がないため、このコマンドをお勧めします。
jamessan 2009

2
これは、OPが回避したsvimの代わりにvimを結ぶことを止めません。
ScaryAardvark、2010

3
-1、これは単に「ファイルを開くときにsudoを入力することを忘れないでください」と言っているだけで、OPはvi内でroot権限を取得する方法を知りたいと考えています。
ブラッドコッホ

-2

考えられる簡単なハックは、編集中のファイルに対してchmodを実行し、vimで保存してから、chmodを使って元のファイルに戻します。

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)

もちろん、セキュリティについて心配しているシステムでは、このアプローチはお勧めしません。数秒の間、誰もが気付かないうちにファイルの読み取りや変更を行えるからです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.