スポンサーリンク
vimでsudoを忘れて書き込み権限がなく、いざ「:w」で保存するときに「E45: 'readonly' オプションが設定されています(! を追加で上書き)」と表示され、「:w!」を実行してみたらみたで「E212: 書き込み用にファイルを開けません」エラーになってしまい、せっかく入力した内容が保存できない、ということはたまにあるかと思います*。「後からsudoしたい」なんてことを思う(え)そんなときに、そのまま保存する方法を紹介します。
*「読込専用」「W10: 警告: 読込専用ファイルを変更します」に気がついていれば。。。逆に、気がついていても。。。なのが今回の方法。
スポンサーリンク
結論
Vimのコマンドで「:w」とする代わりに、「:w !sudo tee % > /dev/null」とします。パスワードが要求されたら、パスワードを入力して書き込み完了です。
参考はこちらです:How does the vim "write with sudo" trick work? - Stack Overflow
この謎コマンドにより、Sudoで保存できます。
以下、この謎コマンドの意味の理解をメモしておきます。
謎コマンドの解説
以下、解説。
「:w」の後ろにいろいろついてる
まず、そもそも「:w」の後ろにいろいろ続いてるのはなんだよ、というのの招待がこちらです。
:[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 |:!|. (引用元)
簡単にいえば、「:w」の後に「!command」と書くことで、外部のcommandを実行できる、というわけです。
今回は、「!sudo tee % > /dev/null」を実行していることになります。
標準入力でコマンドへ
このとき、コマンドへの標準入力として、編集内容が渡されます。
また、「%」で、編集中のファイルパスが渡されます。
catじゃだめ?
となると、「:w !sudo cat > %」でも保存できそうなのですが、「/bin/bash: ○○: 許可がありません」となってしまいます。
これは、sudoがcatには効果があるものの、「>」に効果がなく、結局書き込めない、からです。
teeで標準入力を保存する
これを解決するために利用しているのが「tee」コマンドです。
そもそもteeは、出力を分岐させるために利用するコマンドで、「sudo tee % > /dev/null」で、標準入力がファイル(%)と、/dev/nullへ分岐させられています。
もう役に立たないリダイレクト出力は「/dev/null」へ放り込んでおいて、ファイル名を指定するところで「%」を指定して、リダイレクトを使わずに、標準入力をsudoの影響範囲内でファイルに上書き保存しています。
いざというときに
いざというときに存在を覚えておくとちょっと便利なコマンドの紹介と、自分の理解メモでした。
スポンサーリンク
スポンサーリンク