Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

StackOverflow Point

StackOverflow Point Navigation

  • Web Stories
  • Badges
  • Tags
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Web Stories
  • Badges
  • Tags
Home/ Questions/Q 245429
Next
Alex Hales
  • 0
Alex HalesTeacher
Asked: August 17, 20222022-08-17T05:14:53+00:00 2022-08-17T05:14:53+00:00In: Linux, unix, vi

linux – How do you get sudo access for a file inside the vi text editor?

  • 0

[ad_1]

The most common method of getting around the read-only file problem is to open a pipe to current file as the super-user using an implementation of sudo tee. However, all of the most popular solutions that I have found around the Internet have a combination of a several potential caveats:

  • The entire file gets written to the terminal, as well as the file. This can be slow for large files, especially over slow network connections.
  • The file loses its modes and similar attributes.
  • File paths with unusual characters or spaces might not be handled correctly.

To get around all of these issues, you can use the following command:

" 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'

These can be shortened, respectfully:

:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'

: begins the command; you will need to type this character in normal mode to start entering a command. It should be omitted in scripts.

sil[ent] suppresses output from the command. In this case, we want to stop the Press any key to continue-like prompt that appears after running the :! command.

exec[ute] executes a string as a command. We can’t just run :write because it won’t process the necessary function call.

! represents the :! command: the only command that :write accepts. Normally, :write accepts a file path to which to write. :! on its own runs a command in a shell (for example, using bash -c). With :write, it will run the command in the shell, and then write the entire file to stdin.

sudo should be obvious, since that’s why you’re here. Run the command as the super-user. There’s plenty of information around the ‘net about how that works.

tee pipes stdin to the given file. :write will write to stdin, then the super-user tee will receive the file contents and write the file. It won’t create a new file–just overwrite the contents–so file modes and attributes will be preserved.

shellescape() escapes special characters in the given file path as appropriate for the current shell. With just one parameter, it would typically just enclose the path in quotes as necessary. Since we’re sending to a full shell command line, we’ll want to pass a non-zero value as the second argument to enable backslash-escaping of other special characters that might otherwise trip up the shell.

@% reads the contents of the % register, which contains the current buffer’s file name. It’s not necessarily an absolute path, so ensure that you haven’t changed the current directory. In some solutions, you will see the commercial-at symbol omitted. Depending on the location, % is a valid expression, and has the same effect as reading the % register. Nested inside another expression the shortcut is generally disallowed, however: such as in this case.

>NUL and >/dev/null redirect stdout to the platform’s null device. Even though we’ve silenced the command, we don’t want all of the overhead associated with piping stdin back to vim–best to dump it as early as possible. NUL is the null device on DOS, MS-DOS, and Windows, not a valid file. As of Windows 8 redirections to NUL don’t result in a file named NUL being written. Try creating a file on your desktop named NUL, with or without a file extension: you will be unable to do so. (There are several other device names in Windows that might be worth getting to know.)

Platform-Dependent

Of course, you still don’t want to memorize those and type them out each time. It’s much easier to map the appropriate command to a simpler user command. To do this on POSIX, you could add the following line to your ~/.vimrc file, creating it if it doesn’t already exist:

command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

This will allow you to type the :W (case-sensitive) command to write the current file with super-user permissions–much easier.

Platform-Independent

I use a platform-independent ~/.vimrc file that synchronizes across computers, so I added multi-platform functionality to mine. Here’s a ~/.vimrc with only the relevant settings:

#!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

[ad_2]

  • 0 0 Answers
  • 5 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report
Leave an answer

Leave an answer
Cancel reply

Browse

Sidebar

Ask A Question

Related Questions

  • xcode - Can you build dynamic libraries for iOS and ...

    • 0 Answers
  • bash - How to check if a process id (PID) ...

    • 2 Answers
  • database - Oracle: Changing VARCHAR2 column to CLOB

    • 4 Answers
  • What's the difference between HEAD, working tree and index, in ...

    • 3 Answers
  • Amazon EC2 Free tier - how many instances can I ...

    • 0 Answers

Stats

  • Questions : 43k

Subscribe

Login

Forgot Password?

Footer

Follow

© 2022 Stackoverflow Point. All Rights Reserved.

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.