How do you get sudo access for a file inside the vi text editor?
%
is replaced with the current file name, thus you can use:
:w !sudo tee %
(vim
will detect that the file has been changed and ask whether you want to it to be reloaded. Say yes by choosing [L]
rather than OK.)
As a shortcut, you can define your own command. Put the following in your .vimrc
:
command W w !sudo tee % >/dev/null
With the above you can type :W<Enter>
to save the file. Since I wrote this, I have found a nicer way (in my opinion) to do this:
cmap w!! w !sudo tee >/dev/null %
This way you can type :w!!
and it will be expanded to the full command line, leaving the cursor at the end, so you can replace the %
with a file name of your own, if you like.
How does the vim write with sudo trick work?
In :w !sudo tee %
...
%
means "the current file"
As eugene y pointed out, %
does indeed mean "the current file name", which is passed to tee
so that it knows which file to overwrite.
(In substitution commands, it's slightly different; as :help :%
shows, it's equal to 1,$ (the entire file)
(thanks to @Orafu for pointing out that this does not evaluate to the filename). For example, :%s/foo/bar
means "in the current file, replace occurrences of foo
with bar
." If you highlight some text before typing :s
, you'll see that the highlighted lines take the place of %
as your substitution range.)
:w
isn't updating your file
One confusing part of this trick is that you might think :w
is modifying your file, but it isn't. If you opened and modified file1.txt
, then ran :w file2.txt
, it would be a "save as"; file1.txt
wouldn't be modified, but the current buffer contents would be sent to file2.txt
.
Instead of file2.txt
, you can substitute a shell command to receive the buffer contents. For instance, :w !cat
will just display the contents.
If Vim wasn't run with sudo access, its :w
can't modify a protected file, but if it passes the buffer contents to the shell, a command in the shell can be run with sudo. In this case, we use tee
.
Understanding tee
As for tee
, picture the tee
command as a T-shaped pipe in a normal bash piping situation: it directs output to specified file(s) and also sends it to standard output, which can be captured by the next piped command.
For example, in ps -ax | tee processes.txt | grep 'foo'
, the list of processes will be written to a text file and passed along to grep
.
+-----------+ tee +------------+
| | -------- | |
| ps -ax | -------- | grep 'foo' |
| | || | |
+-----------+ || +------------+
||
+---------------+
| |
| processes.txt |
| |
+---------------+
(Diagram created with Asciiflow.)
See the tee
man page for more info.
Tee as a hack
In the situation your question describes, using tee
is a hack because we're ignoring half of what it does. sudo tee
writes to our file and also sends the buffer contents to standard output, but we ignore standard output. We don't need to pass anything to another piped command in this case; we're just using tee
as an alternate way of writing a file and so that we can call it with sudo
.
Making this trick easy
You can add this to your .vimrc
to make this trick easy-to-use: just type :w!!
.
" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %
The > /dev/null
part explicitly throws away the standard output, since, as I said, we don't need to pass anything to another piped command.
How would I create a text file and fill it with sudo permission in bash
The question has been edited to include a log of the problem being introduced, which includes the command:
# Taken from edited question
$ echo 'hello' > sudo tee /data/hello
In bash (which allows redirection operators at any point in a simple command), this is precisely equivalent to running:
# From question, with redirection moved to end to make actual behavior more readable
echo 'hello' tee /data/hello > sudo
That is, it's creating a file named sudo
in your current directory, not using sudo
to run tee
(in the above, tee
is just an argument to echo
).
What you want, by contrast, is:
# CORRECT: Using a pipe, not a redirection
echo 'hello' | sudo tee /data/hello
with a pipe (|
) rather than a >
.
/etc/apt/sources.list E212: Can't open file for writing
Vim has a builtin help system. Running :h E212
inside Vim prints the following:
For some reason the file you are writing to cannot be created or overwritten.
The reason could be that you do not have permission to write in the directory
or the file name is not valid.
You might want to edit the file as a superuser with sudo vim FILE
. Or if you don't want to leave your existing vim session (and now have proper sudo rights), you can run:
:w !sudo tee % > /dev/null
Which will save the file.
How to edit a text file in my terminal
Open the file again using vi. and then press the insert button to begin editing it.
How to change file permission from within vi
Just use
:!chmod +w %
in command mode. % will be replaced by the current file name.
Related Topics
Linux: Writes Are Split into 512K Chunks
Aslr Bits of Entropy of Mmap()
Remove File Coding Mark But Preserve Its Coding
Merge Files with Bash by Primary Key
Extending a Script to Loop Over Multiple Files and Generate Output Names
How to Make Grep Print the Lines Below and Above Each Matching Line
How to Check in Bash Whether a File Was Created More Than X Time Ago
Bash Foreach Loop Works Differently When Executed from .Sh File
Determining the Path That a Yum Package Installed To
Redirecting Tcp-Traffic to a Unix Domain Socket Under Linux
Mechanism of Clipboard of Xwindow
Best Way Elevate the Privileges Programmatically Under Different Versions of Linux
How to Get Details of All Modules/Drivers That Were Initialized/Probed During the Linux Kernel Boot
Gdb: Redirect Target Stdout Temporarly
Why Do My Results Different Following Along the Tiny Asm Example
Quick Unix Command to Display Specific Lines in the Middle of a File