Bagaimana cara `: w! Sudo tee%` bekerja

27

Jika Anda membuka file yang Anda tidak memiliki izin untuk menulis di vim, maka memutuskan Anda perlu mengubahnya, Anda dapat menulis perubahan Anda tanpa keluar vim dengan melakukan :w !sudo tee %
Saya tidak mengerti bagaimana ini bisa bekerja. Bisakah Anda membedah ini?
Saya mengerti :wbagian itu, ia menulis buffer saat ini ke disk, dengan asumsi sudah ada nama file yang terkait dengannya, kan?
Saya juga mengerti !yang mengeksekusi sudo teeperintah dan %mewakili konten buffer saat ini kan?
Tetapi masih tidak mengerti bagaimana ini bekerja.

Ali
sumber

Jawaban:

30

Struktur ini :w !cmdberarti "tulis buffer saat ini yang disalurkan melalui perintah". Jadi Anda bisa melakukannya, misalnya :w !catdan itu akan menyalurkan buffer cat.

Sekarang %adalah nama file yang terkait dengan buffer

Jadi :w !sudo tee %akan menyalurkan isi buffer melalui sudo tee FILENAME. Ini secara efektif menulis isi buffer ke file.

Stephen Harris
sumber
Dan apa itu tee?
CodyBugstein
7

% mewakili nama file buffer saat ini, bukan isinya.

jadi :w !sudo tee %artinya pipa buffer saat ini ke sudo tee [currentfilename].

tee sedang dijalankan sebagai root, sehingga memiliki akses tulis untuk menyimpan stdin ke file.

Lihat juga /programming/2600783/how-does-the-vim-write-with-sudo-trick-work

cas
sumber
2

Tidak benar!

!commandmenjalankan perintah sebagai perintah filter , yang mengambil teks dari stdin, melakukan sesuatu dan output stdout.

Dengan menggunakan w, Anda mendorong isi file ke stdindari sudo tee %. %adalah register khusus dalam vim, yang menyimpan nama file saat ini.

Jadi Anda dapatkan sudo tee FILENAME, yang akan mendorong tee stdin- konten file - ke file saat ini.

cuonglm
sumber
2
:!commandadalah filter (lih. :h !), sementara :w !commandtidak, itu hanya dijalankan commanddengan file saat ini sebagai stdin(lih :h :w_c.). Intinya: :w !sed /./dtidak mengubah konten buffer saat ini. Tapi resep ini memang tidak cukup tepat untuk alasan lain, %perlu melarikan diri: :exec 'w !sudo tee ' . shellescape(expand('%', 1)). Perintah asli tidak bekerja dengan, katakanlah, nama file dengan spasi.
Satō Katsura