Caveats ทั่วไป
วิธีที่พบมากที่สุดของการแก้ไขปัญหาไฟล์อ่านอย่างเดียวคือการเปิดท่อไปยังแฟ้มปัจจุบันเป็นผู้ใช้ super 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()
หนีอักขระพิเศษในพา ธ ไฟล์ที่กำหนดตามความเหมาะสมสำหรับเชลล์ปัจจุบัน ด้วยพารามิเตอร์เพียงตัวเดียวโดยทั่วไปแล้วมันจะล้อมรอบด้วยเครื่องหมายคำพูดตามความจำเป็น เนื่องจากเรากำลังส่งไปยังบรรทัดคำสั่งเชลล์แบบเต็มเราจะต้องการส่งค่าที่ไม่เป็นศูนย์เป็นอาร์กิวเมนต์ที่สองเพื่อเปิดใช้งานเครื่องหมายทับขวาของอักขระพิเศษอื่น ๆ ที่อาจทำให้เปลือกขึ้น
@%
อ่านเนื้อหาของ%
รีจิสเตอร์ซึ่งมีชื่อไฟล์บัฟเฟอร์ปัจจุบัน ไม่จำเป็นต้องเป็นพา ธ สัมบูรณ์ดังนั้นโปรดตรวจสอบให้แน่ใจว่าคุณไม่ได้เปลี่ยนไดเรกทอรีปัจจุบัน ในการแก้ไขปัญหาบางอย่างคุณจะเห็นสัญลักษณ์การค้าที่ถูกละเว้น %
เป็นนิพจน์ที่ถูกต้องและมีผลเหมือนกับการอ่านการ%
ลงทะเบียนทั้งนี้ขึ้นอยู่กับตำแหน่ง ซ้อนกันภายในนิพจน์อื่นทางลัดไม่ได้รับอนุญาตโดยทั่วไปอย่างไรก็ตามเช่นในกรณีนี้
>NUL
และ>/dev/null
เปลี่ยนเส้นทางstdout
ไปยังอุปกรณ์ null ของแพลตฟอร์ม แม้ว่าเราได้สั่งให้เงียบคำสั่ง แต่เราไม่ต้องการให้ค่าใช้จ่ายทั้งหมดที่เกี่ยวข้องกับstdin
การไพพ์กลับไปเป็นกลุ่ม - ดีที่สุดที่จะทิ้งมันให้เร็วที่สุด NUL
เป็นอุปกรณ์ null ใน DOS, MS-DOS และ Windows ไม่ใช่ไฟล์ที่ถูกต้อง ตั้งแต่การเปลี่ยนเส้นทาง 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