รับการอนุญาตรูทบนไฟล์ภายใน vi? [ปิด]


245

บ่อยครั้งในขณะที่แก้ไขไฟล์กำหนดค่าฉันจะเปิดด้วย vi และเมื่อฉันไปเพื่อบันทึกจะรู้ว่าฉันไม่ได้พิมพ์

sudo vi filename

มีวิธีใดบ้างที่จะให้สิทธิพิเศษในการบันทึกไฟล์? ฉันดูเหมือนจะจำบางสิ่งบางอย่างเกี่ยวกับเรื่องนี้ในขณะที่ค้นหาบางสิ่งบางอย่างเกี่ยวกับ vi ในขณะที่ แต่ตอนนี้ฉันไม่สามารถหามัน


อาจจะเพียงแค่บันทึกสำเนาไว้ในโฮมไดเร็กตอรี่ของคุณและ "sudo mv" ในภายหลัง
Paan

คำตอบ:


296

% ถูกแทนที่ด้วยชื่อไฟล์ปัจจุบันดังนั้นคุณสามารถใช้:

:w !sudo tee %

( vimจะตรวจพบว่าไฟล์มีการเปลี่ยนแปลงและถามว่าคุณต้องการโหลดซ้ำหรือไม่ตอบว่าใช่โดยเลือก[L]แทนตกลง)

เป็นทางลัดคุณสามารถกำหนดคำสั่งของคุณเอง ใส่สิ่งต่อไปนี้ในของคุณ.vimrc:

command W w !sudo tee % >/dev/null

ด้วยการข้างต้นคุณสามารถพิมพ์:W<Enter>เพื่อบันทึกไฟล์ ตั้งแต่ฉันเขียนสิ่งนี้ฉันพบวิธีที่ดีกว่า (ในความคิดของฉัน) เพื่อทำสิ่งนี้:

cmap w!! w !sudo tee >/dev/null %

วิธีนี้คุณสามารถพิมพ์:w!!และจะขยายเป็นบรรทัดคำสั่งแบบเต็มปล่อยเคอร์เซอร์ไว้ท้ายเพื่อให้คุณสามารถแทนที่%ด้วยชื่อไฟล์ของคุณเองหากคุณต้องการ


5
ใช้งานได้ใน gvim หรือไม่ การรันคำสั่งเป็นสาเหตุให้กลุ่มแจ้งรหัสผ่าน แต่ไม่ยอมรับอินพุต ในที่สุดก็ออกมาในครั้งที่สองพยายามและพูดว่า:sudo: 1 incorrect password attempt
cmcginty

ฉันจะเห็นว่าไม่มีเหตุผลสำหรับ gvim ที่จะทำงานแตกต่างกัน ... คุณแน่ใจหรือว่า sudo ด้วยตัวเองทำงานอย่างถูกต้อง?

หากคุณต้องการสิทธิ์พิเศษในการบันทึกไฟล์ใหม่ให้แทนที่% ด้วยชื่อ (รวมถึงพา ธ ) ของไฟล์ใหม่
gvkv

บางครั้งคุณต้องเพิ่มผู้ใช้ของคุณในไฟล์ sudoer ก่อนป้อนผู้ใช้รูทและเปิด/etc/sudoersไฟล์เพิ่มyour_username ALL=(ALL) ALLใต้บรรทัดroot ALL=(ALL) ALLเลิกและบันทึก
สุดยอด

1
@Coolesting: 1) มีอีกประมาณพันสิ่งที่คุณต้องทำ…เราไม่สามารถแสดงรายการทั้งหมดได้ 2) visudoคุณควรใช้

32

โดยทั่วไปคุณไม่สามารถเปลี่ยนรหัสผู้ใช้ที่มีประสิทธิภาพของกระบวนการ vi แต่คุณสามารถทำได้:

:w !sudo tee myfile

1
:w !sudo tee % >/dev/nullหรือ:w !sudo dd of=%หลีกเลี่ยงการมีเนื้อหาของไฟล์ที่สะท้อนกลับเป็นไฟล์ที่ถูกบันทึก
27499 jamessan

คุณอธิบายได้ไหมว่ามันทำงานอย่างไร ฉันค้นหาteeและดูว่าเป็นคำสั่ง Unix pipe และ!แทรกคำสั่ง shell การ:wเขียนไปยังมาตรฐานออกซึ่งได้รับการประปาโดยtee?
Eric Hu

4
@Eric ถูกต้อง คำสั่ง "tee myfile" จะคัดลอก stdin ไปยัง myfile การรัน "sudo tee myfile" จะทำเช่นเดียวกัน แต่เนื่องจากกระบวนการ tee เป็นเจ้าของโดย root myfile ก็จะเป็นเจ้าของเช่นกัน ที่ด้าน vi, ": w! command line" จะไปป์ไลน์ทั้งหมดไปที่ "some command line"
มาร์คแฮร์ริสัน

16

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) ด้วยก็จะเรียกใช้คำสั่งในเปลือกแล้วเขียนไฟล์ทั้งหมดไป:writestdin

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

ถ้าคุณเดินทาง Windows ด้วยการสร้างไฟล์ที่สามารถเขียนได้ทั่วโลกที่ C: \ dev \ null
Paul Stelian

1
@ PaulStelian เป็นไปได้ แต่ไม่น่าเป็นไปได้ คุณสามารถขยายรหัสนี้ไปยังบัญชีสำหรับแพลตฟอร์มและสถานการณ์ที่หลากหลายได้อย่างง่ายดาย ในความเป็นจริงคุณไม่น่าจะประสบกับสถานการณ์บน Windows ที่sudoมีอยู่จริง แต่ไม่ได้/dev/nullดังนั้นคุณจะต้องได้รับมากกว่านี้หากคุณต้องการการสนับสนุนข้ามแพลตฟอร์มที่แท้จริง มันเป็นการแนะนำเพิ่มเติม - อาหารสำหรับความคิด :)
Zenexer

11

หากคุณกำลังใช้เป็นกลุ่มมีสคริปต์ที่มีอยู่ชื่อsudo.vim หากคุณพบว่าคุณเปิดไฟล์ที่คุณต้องการเข้าถึงรูทเพื่ออ่านให้พิมพ์

: e sudo:%
Vim จะแทนที่% ด้วยชื่อของไฟล์ปัจจุบันและsudo:สั่งให้สคริปต์ sudo.vim ทำหน้าที่แทนการอ่านและเขียน


4
ฉันไม่แนะนำให้ใช้สคริปต์นี้เนื่องจากไม่ได้ใช้ความระมัดระวังอย่างเหมาะสมกับการหลีกเลี่ยงชื่อไฟล์
27499 jamessan

7

คำแนะนำของไรอันนั้นดีอย่างไรก็ตามถ้าทำตามขั้นตอนที่ 3 อย่าย้ายไฟล์ชั่วคราว มันจะมีความเป็นเจ้าของและสิทธิ์ที่ไม่ถูกต้อง แต่sudoeditไฟล์ที่ถูกต้องและอ่านในเนื้อหา (ใช้:rหรือไม่ชอบ) ของไฟล์ชั่วคราว

หากทำตามขั้นตอนที่ 2 ให้ใช้:w!เพื่อบังคับให้เขียนไฟล์


3

เมื่อคุณเข้าสู่โหมดแทรกไฟล์ที่คุณต้องการเข้าถึง sudo เพื่อแก้ไขคุณจะได้รับข้อความบอกสถานะ

-- INSERT -- W10: Warning: Changing a readonly file

ถ้าฉันคิดถึงเรื่องนั้นโดยทั่วไปฉันก็ทำ

:w ~/edited_blah.tmp
:q

..then ..

sudo "cat edited_blah.tmp > /etc/blah"

..หรือ..

sudo mv edited_blah.tmp /etc/blah

อาจมีวิธีวงเวียนน้อยกว่าที่จะทำ แต่มันใช้งานได้


cat $ tmp> $ target เป็นครีเอทีฟ แต่มีเหตุผลใดที่ไม่เพียงแค่ sudo mv ไฟล์?
ojrac

จุดที่ดี .. นอกจากนี้ยังมีปัญหาใหญ่กับบางสิ่งบางอย่างแมว sudo> / etc / blah - ที่จะใช้ sudo แมวไฟล์แล้วผู้ใช้ปกติที่จะเขียนถึง / etc / blah (ซึ่งจะไม่ทำงาน) .. แก้ไขใน คำตอบและเพิ่มข้อเสนอแนะ sudo mv ที่ดีขึ้นของคุณ ..
dbr

คำแนะนำ mv ไม่สงวนสิทธิ์
Paul Stelian

1

Google ที่รวดเร็วดูเหมือนจะให้คำแนะนำนี้:

  1. อย่าพยายามแก้ไขหากเป็นแบบอ่านอย่างเดียว
  2. คุณอาจสามารถเปลี่ยนการอนุญาตในไฟล์ (ไม่ว่าจะช่วยให้คุณประหยัดหรือไม่ก็ขึ้นอยู่กับการทดลอง)
  3. หากคุณยังคงแก้ไขอยู่ให้บันทึกเป็นไฟล์ชั่วคราวจากนั้นย้ายไฟล์

http://ubuntuforums.org/showthread.php?t=782136


1

นี่คืออีกหนึ่งที่ปรากฏขึ้นตั้งแต่ตอบคำถามนี้ปลั๊กอินที่เรียกว่า SudoEdit ซึ่งมีฟังก์ชั่น SudoRead และ SudoWrite ซึ่งโดยปกติแล้วจะพยายามใช้ sudo ก่อนและ su หากล้มเหลว: http://www.vim.org/scripts/ script.php? SCRIPT_ID = 2709


0

ฉันมีสิ่งนี้ใน ~ / .bashrc ของฉัน:

alias svim='sudo vim'

ตอนนี้เมื่อใดก็ตามที่ฉันต้องการแก้ไขไฟล์กำหนดค่าฉันเพิ่งเปิดด้วย svim


2
sudoeditคำสั่งควรเป็นที่ต้องการเพราะมันไม่จำเป็นต้องทำงานเป็นกลุ่มเป็นราก
jamessan

2
สิ่งนี้ยังไม่หยุดคุณผูกเสียงเรียกเข้าแทน svim ซึ่งเป็นสิ่งที่ OP หลบหนีไป
ScaryAardvark

3
-1, นี่คือการพูดว่า "อย่าลืมพิมพ์ sudo เมื่อเปิดไฟล์", OP ต้องการทราบว่าพวกเขาจะได้รับสิทธิ์รูตภายใน vi ได้อย่างไร
แบรดโคช์

-2

แฮ็คด่วนที่คุณสามารถพิจารณาได้คือทำ 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)

แน่นอนว่าฉันไม่แนะนำวิธีนี้ในระบบที่คุณกังวลเกี่ยวกับความปลอดภัยเพราะไม่กี่วินาทีที่ทุกคนสามารถอ่าน / เปลี่ยนแปลงไฟล์โดยที่คุณไม่รู้ตัว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.