Отримання дозволів root на файл усередині vi? [зачинено]


245

Часто під час редагування конфігураційних файлів я відкрию один з vi і тоді, коли йду його зберегти, зрозумію, що я не вводив

sudo vi filename

Чи є якийсь спосіб надати vi sudo привілеї для збереження файлу? Мені здається, я пригадую щось про це, коли я шукав деякі речі про vi деякий час тому, але зараз не можу його знайти.


може просто зберегти копію в домашній директорії і «Суду мв» пізніше
паан

Відповіді:


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
Чи працює це у гвімі? Виконання команди змушує Vim запросити пароль, але не приймати введення. Врешті-решт, час вичерпується на дві спроби і каже:sudo: 1 incorrect password attempt
cmcginty

я б не бачив причин, щоб gvim поводився інакше ... ти впевнений, що судо само по собі працює правильно?

Якщо вам потрібні привілеї root для збереження нового файлу, замініть% на ім'я (включаючи шлях) нового файлу.
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=%уникайте того, щоб вміст файлу повторювався, коли файл зберігається.
Jamessan

Чи можете ви пояснити, як це працює? Я підняв голову teeі бачу, що це команда Unix pipe, і !вставляє команду shell. Чи стандартне :wнаписання, яке виходить tee?
Ерік Ху

4
@Eric, це правильно. команда "tee myfile" буде копіювати stdin у myfile. запуск "sudo tee myfile" зробить те саме, але оскільки процес трійника належить корінь, myfile також буде належати root. З боку vi, ": w! Деякий командний рядок" передасть усі рядки в "деякий командний рядок".
Марк Гаррісон

16

Загальні каверзи

Найпоширеніший спосіб вирішити проблему з файлом, доступним лише для читання, - це відкрити трубку для поточного файлу як суперкористувача за допомогою реалізації 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на нульовий пристрій платформи. Незважаючи на те, що ми замовкли команду, ми не хочемо, щоб усі накладні витрати, пов’язані з переходом stdinназад до vim, - найкраще скинути її якомога раніше. NULє нульовим пристроєм у 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?
Пол Стеліан

1
@PaulStelian Можливо, але малоймовірно. Ви можете легко розширити цей код для врахування різних платформ та обставин. Насправді ви навряд чи зіткнетеся з ситуацією в Windows, де sudoіснує, але ні /dev/null, тому вам потрібно буде захоплюватися, якби вам потрібна справжня міжплатформна підтримка. Це більше вступ - їжа для роздумів. :)
Zenexer

11

Якщо ви використовуєте Vim , доступний сценарій з назвою sudo.vim . Якщо ви виявили, що ви відкрили файл, до якого потрібно читати кореневий доступ, введіть

: e sudo:%
Vim замінює% на ім'я поточного файлу та sudo:вказує скрипт sudo.vim взяти на себе читання та запис.


4
Я б не рекомендував використовувати цей скрипт, оскільки він не вживає належних запобіжних заходів щодо усунення імен файлів.
Jamessan

7

Поради Райана, як правило, хороші, але якщо виконувати крок 3, не переміщуйте тимчасовий файл; це буде неправильне право власності та дозволи. Натомість sudoeditвиправте файл та прочитайте у вмісті (використовуючи :rчи подібне) тимчасовий файл.

Якщо виконується наступний крок 2, використовуйте :w!для запису файл.


3

Коли ви переходите в режим вставки файлу, вам потрібен доступ для редагування sudo, ви отримуєте повідомлення про стан

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

Якщо я пропускаю це, взагалі роблю

:w ~/edited_blah.tmp
:q

..тоді..

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

.. або ..

sudo mv edited_blah.tmp /etc/blah

Напевно, існує менш обхідний спосіб зробити це, але це працює.


cat $ tmp> $ target творчий, але чи є якась причина не просто судо mv файл?
ojrac

Хороший момент .. Існувала також велика проблема із судо-кішкою чогось> / etc / blah - це використовує sudo для перетворення файлу, потім звичайний користувач записувати в / etc / blah (який звичайно працює). Виправлено це в відповідь, і додав ваш кращий Судо мВ пропозицію ..
DBR

Пропозиція mv не зберігає дозволи.
Пол Стеліан

1

Схоже, швидкий Google дає такі поради:

  1. Не намагайтеся редагувати, якщо це лише для читання.
  2. Ви можете змінити дозволи на файл. (Незалежно від того, чи дозволить вам заощадити, це залежить від експерименту.)
  3. Якщо ви все-таки все-таки редагували, збережіть у тимчасовому файлі та перемістіть його.

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



0

Я маю це у своєму ~ / .bashrc:

alias svim='sudo vim'

Тепер, коли мені потрібно редагувати конфігураційний файл, я просто відкриваю його з усіма.


2
sudoeditКоманда повинна бути кращим , оскільки він не вимагає працює Vim в якості кореня.
Jamessan

2
Це все ще не перешкоджає вам прив'язувати vim замість усіх, до чого ухиляється ОП.
ScaryAardvark

3
-1, Це просто говорить "не забудьте набрати sudo під час відкриття файлу", ОП хоче знати, як вони можуть отримати кореневі привілеї всередині 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)

Звичайно, я не рекомендую такий підхід у системі, де ви переживаєте за безпеку, оскільки протягом декількох секунд кожен може прочитати / змінити файл, не розуміючи.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.