質問
設定ファイルを編集しているときに、vi で設定ファイルを開いて保存しようとしたときに、入力していないことに気づくことがよくあります。
sudo vi filename
ファイルを保存するための vi sudo 権限を与える方法はありますか?少し前に vi について調べているときにこれについて何かを見た記憶があるようですが、今は見つかりません。
解決
%
は現在のファイル名に置き換えられるため、次のように使用できます。
:w !sudo tee %
(vim
ファイルが変更されたことを検出し、ファイルを再ロードするかどうかを尋ねます。選択して「はい」と言う [L]
OKではなく。)
ショートカットとして、独自のコマンドを定義できます。以下を入力してください .vimrc
:
command W w !sudo tee % >/dev/null
上記で入力できます :W<Enter>
ファイルを保存します。これを書いて以来、(私の意見では)これを行うためのより良い方法を見つけました。
cmap w!! w !sudo tee >/dev/null %
このようにして入力できます :w!!
コマンドライン全体に展開され、カーソルが最後に残るので、 %
必要に応じて、独自のファイル名を付けます。
他のヒント
一般に、vi プロセスの実効ユーザー ID は変更できませんが、これは可能です。
:w !sudo tee myfile
一般的な注意事項
読み取り専用ファイルの問題を回避する最も一般的な方法は、次の実装を使用してスーパーユーザーとして現在のファイルへのパイプを開くことです。 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()
現在のシェルに応じて、指定されたファイル パス内の特殊文字をエスケープします。パラメーターが 1 つだけの場合、通常は必要に応じてパスを引用符で囲むだけになります。完全なシェル コマンド ラインに送信しているため、2 番目の引数としてゼロ以外の値を渡し、シェルでエラーが発生する可能性がある他の特殊文字のバックスラッシュ エスケープを有効にします。
@%
の内容を読み取ります %
現在のバッファのファイル名を含むレジスタ。必ずしも絶対パスである必要はないため、現在のディレクトリを変更していないことを確認してください。一部のソリューションでは、commercial-at 記号が省略されていることがあります。場所によっては、 %
は有効な式であり、 %
登録する。ただし、別の式内にネストされたショートカットは通常は許可されません。この場合のように。
>NUL
そして >/dev/null
リダイレクト stdout
プラットフォームのヌルデバイスに送信します。コマンドを沈黙させたとしても、パイプ処理に関連するすべてのオーバーヘッドは望ましくない stdin
vim に戻ります -- できるだけ早くダンプするのが最善です。 NUL
は、DOS、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
関連する設定のみを使用します。
#!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
Ryan のアドバイスは一般的には適切ですが、ステップ 3 に従う場合は、一時ファイルを移動しないでください。間違った所有権と権限を持つことになります。その代わり、 sudoedit
正しいファイルを選択し、その内容を読み込みます(使用して :r
など)の一時ファイル。
ステップ 2 に従う場合は、使用します :w!
ファイルの書き込みを強制します。
編集するには 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
もっと回りくどい方法があるかもしれませんが、それはうまくいきます。
Google で調べてみると、次のようなアドバイスが得られるようです。
- 読み取り専用の場合は編集しないでください。
- ファイルのアクセス許可を変更できる場合があります。(保存できるかどうかは実験次第です。)
- それでも編集した場合は、一時ファイルに保存してから移動します。
この質問が回答されてから登場したもう 1 つのプラグインは、SudoRead 関数と SudoWrite 関数を提供する SudoEdit というプラグインです。このプラグインは、デフォルトで最初に sudo を使用し、それが失敗した場合は su を使用しようとします。 http://www.vim.org/scripts/script.php?script_id=2709
私の ~/.bashrc にはこれがあります:
alias svim='sudo vim'
今では、設定ファイルを編集する必要があるときは、svim でファイルを開くだけです。
考えられる簡単なハックは、編集中のファイルに 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)
もちろん、セキュリティが心配なシステムではこのアプローチはお勧めしません。数秒間は誰でも気付かずにファイルを読み取ったり変更したりできるからです。
使用 グクスド の代わりに 須藤 GVimの場合、つまり
cmap w!! w !gksudo tee >/dev/null %