1. ホーム

[解決済み】vimの「sudoで書く」トリックはどうやるの?

2022-03-18 13:54:44

質問

sudoでvimを開くのを忘れた場合でも、root権限が必要なファイルに書き込むことができるコマンドを見たことがある人は多いのではないでしょうか。

:w !sudo tee %

ここで具体的に何が起こっているのかがわからないということです。

私はすでにこれを理解しています。 w はこのためにある

                                                        *:w_c* *:write_c*
:[range]w[rite] [++opt] !{cmd}
                        Execute {cmd} with [range] lines as standard input
                        (note the space in front of the '!').  {cmd} is
                        executed like with ":!{cmd}", any '!' is replaced with
                        the previous command |:!|.

ということで、すべての行を標準入力として渡しています。

!sudo tee の部分は tee をAdministrator権限で実行します。

すべてを理解するためには % のパラメータとして)ファイル名を出力する必要があります。 tee しかし、この動作についての参考文献をヘルプで見つけることができません。

tl;dr どなたかこのコマンドを分解するのを手伝っていただけませんか?

どのように解決するのですか?

:w !sudo tee % ...

% は、現在のファイルという意味です。

として eugene y さんのご指摘 , % は確かに "現在のファイル名" を意味し、このファイル名は tee どのファイルを上書きすればよいかがわかるようにするためです。

(代入コマンドの場合、若干異なります。 :help :% が示すように、これは equal to 1,$ (the entire file) (これがファイル名に対して評価されないことを指摘してくれた @Orafu に感謝します)。例えば :%s/foo/bar は " を意味します。 現在のファイルでは の出現を置き換える。 foobar ." を入力する前にテキストをハイライトした場合 :s の代わりにハイライトされた行が表示されるのがわかるだろう。 % を置換範囲として使用します)。

:w がファイルを更新していない

このトリックの紛らわしいところは、次のように考えてしまうことです。 :w はファイルを変更していますが、そうではありません。もしあなたがファイルを開いて file1.txt を実行し、その後 :w file2.txt の場合、"save as"になってしまいます。 file1.txt は変更されませんが、現在のバッファの内容が file2.txt .

の代わりに file2.txt であれば バッファの内容を受け取るシェルコマンドに置き換えます。 . 例えば :w !cat は内容を表示するだけです。

Vim が sudo アクセスで実行されていない場合、その :w は保護されたファイルを変更することはできませんが、バッファの内容をシェルに渡すのであれば。 シェル内のコマンド できる sudoで実行される . この場合 tee .

ティーを理解する

については tee をイメージしてください。 tee コマンドは、通常の bash のパイプ処理における T 字型パイプのようなものです。 また、標準出力に送る 次のパイプコマンドでキャプチャできます。

例えば ps -ax | tee processes.txt | grep 'foo' の場合、プロセスのリストはテキストファイルに書き込まれます。 に渡される。 grep .

     +-----------+    tee     +------------+
     |           |  --------  |            |
     | ps -ax    |  --------  | grep 'foo' |
     |           |     ||     |            |
     +-----------+     ||     +------------+
                       ||   
               +---------------+
               |               |
               | processes.txt |
               |               |
               +---------------+

(で作成した図 アッシーフロー .)

をご覧ください。 tee マンページ をご覧ください。

ハックとしてのティー

ご質問のような状況では を使って tee は、その機能の半分を無視することになるので、ハックとなります。 . sudo tee はファイルに書き込み、バッファの内容を標準出力に送りますが 標準出力を無視する . この場合、他のパイプ付きコマンドに何かを渡す必要はありません。 tee を呼び出すことができます。 sudo .

この仕掛けを簡単にする

を追加することができます。 .vimrc と入力するだけで、このトリックを簡単に使うことができます。 :w!! .

" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %

> /dev/null 部分 明示的に は標準出力を捨てます。先ほど言ったように、パイプでつながれた他のコマンドに何も渡す必要はありませんから。