Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What to do when VI/VIM edits a file without permission to save under Linux environment

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly shows you "how to save VI/VIM files without permission under Linux environment", the content is simple and easy to understand, clear organization, I hope to help you solve doubts, let Xiaobian lead you to study and learn "VI/VIM files without permission under Linux environment" This article bar.

In Linux environment, if you directly use VI/VIM command to edit a file without modification permission, the user will be prompted that the save operation cannot be performed when saving. The general solution can only be to close the file and re-open the file with sudo permission before editing (provided that the user has sudo permission). In fact, in VI/VIM mode through some simple commands, you can save the file without closing the current file.

method one

About %! sudo tee % > /dev/null

This command is executed by passing the current file (i.e.%) as stdin to sudo tee.

methodology II

Friends who work on Linux have probably encountered a situation where when you finish editing a file with Vim, run:wq save exit, and suddenly an error pops up:

E45: 'readonly' option is set (add ! to override)

This indicates that the file is read-only, follow the prompts and add! Force save: :w!, Another error occurred:

"readonly-file-name" E212: Can't open file for writing

The file clearly exists, why does it prompt that it cannot be opened? What does this error represent? View documentation:help E212:

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.

It turned out that there might be no authority to cause it. At this point, you remember that this file needs root permission to edit, and the current login is only an ordinary user. Before editing, you forgot to use sudo to start Vim, so the save failed. So to prevent the changes from being lost, you have to save it as another temporary file temp-file-name, exit Vim, and run sudo mv temp-file-name readonly-file-name to overwrite the original file.

However, this operation is too cumbersome. And if you just want to temporarily store this file and need to modify it, you want to keep the working state of Vim, such as editing history, buffer state, etc. What should I do? Can I get root privileges to save this file without exiting Vim?

solutions

The answer is yes, just execute this command:

:w ! sudo tee %

Let's analyze why this command works. First look at the document:help :w, scroll down a little bit and you'll see:

*:w_c* *:write_c*:[range]w[rite] [++opt] ! {cmd} Execute {cmd} with [range] lines as standard input (note the space in front of the '! '). {cmd} is executed like with ":! {cmd}", any '! ' is replaced with the previous command |:!|. The default [range] for the ":w" command is the whole buffer (1,$)

This method corresponds to the previous command, as follows:

: w ! sudo tee %| | | |:[range]w[rite] [++opt] ! {cmd}

We do not specify range, see the bottom line of the help documentation, and when range is not specified, the entire file defaults. Also, no opt is specified here.

Execute external commands in Vim

Next is an exclamation mark, It indicates that the next part is an external command, sudo tee %. The documentation makes it clear that this is the same as executing directly:! {cmd}It's the same effect. The latter is used to open a shell and execute a command, such as:! ls, which displays all files in the current working directory, is useful because any command that can be executed in shell can be run without exiting Vim and the results can be read into Vim. Imagine if you wanted to insert the current working path or all the file names under the current working path into Vim, you could run:

:r ! pwd or:r ! ls

At this point everything is read into Vim without exiting Vim, executing the command, and then copying and pasting into Vim. With it, Vim is free to operate the shell without exiting.

Another form of command

Look at the previous document:

Execute {cmd} with [range] lines as standard input

So actually this:w doesn't really save the current file, just like when executing:w new-file-name, it saves the contents of the current file to another new-file-name file, where it's equivalent to a save as, not a save. It writes the contents of the current document to the standard input of cmd, and then executes cmd, so the whole command can be converted to a normal shell command with the same function:

$ cat readonly-file-name | sudo tee %

It looks more "normal." sudo is easy to understand, meaning to switch to root to execute the following command, tee and % are what?

Meaning of %

Let's look at % first, and execute:help cmdline-special to see:

In Ex commands, at places where a file name can be used, the following

characters have a special meaning. These can also be used in the expression

function expand() |expand()|.

% Is replaced with the current file name. *:_%* *c_%*

When executing an external command, % expands to the current filename, so cmd above becomes sudo tee readonly-file-name. At this point, the entire command is:

$ cat readonly-file-name | sudo tee readonly-file-name

Note: in another place we often use %, yes, substitution. But there % works differently, execute:help :% View documentation:

Line numbers may be specified with: *:range* *E14* *{address}*

{number} an absolute line number

...

% equal to 1,$ (the entire file) *:%*

In substitution, % means the entire file, not the file name. So for the command:%s/old/new/g, it means replacing old with new throughout the document, not old with new in the filename.

Tee's role

There is only one problem: tee. What does it do? Wikipedia has a detailed explanation, and you can also check out the man page. Here's an example of how tee works:

The output of ls -l is piped to tee, who does two things: first, copies a copy of the data to the file file.txt, and then copies a copy to its standard output. The data is piped to standard input of less again, so it makes a copy of the data and saves it to a file without affecting the original pipeline. Looking at the middle part of the image above, it looks a lot like the capital letter T, adding a branch to the flow of data and hence the name tee.

Now that the above command is easy to understand, tee writes the contents of its standard input to readonly-file-name, thus updating the read-only file. Of course, there is actually another half of the data here: tee's standard output, but because there are no other commands, this output is equivalent to being discarded. Of course, you can also add> /dev/null to explicitly discard the standard output, but this has no effect on the overall operation and increases the number of characters input, so just the above command.

After the order is executed

After running the above command, the following prompt will appear:

W12: Warning: File "readonly-file-name" has changed and the buffer was changed in Vim as well

See ":help W12" for more info.

[O]K, (L)oad File:

Vim prompts for file updates and asks whether to confirm or reload the file. It is recommended to enter O directly, because this can keep the working state of Vim, such as editing history, buffer, etc., and undo operations can still continue. If you select L, the file opens as a brand new file, all work state is lost, undo cannot be performed, and the contents of the buffer are emptied.

A simpler solution: mapping

The above method solves the problem raised at the beginning of the article perfectly, but after all, the command is still a bit long. In order to avoid entering a long string of commands at a time, you can map it to a simple command and add it to.vimrc:

" Allow saving of files as sudo when I forgot to start vim using sudo.

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

This is easy to do:W! That's it. The second half of the command> /dev/null was explained earlier and acts to explicitly drop the contents of standard output.

another way of thinking

So far, a more perfect but tricky solution has been completed. You might ask, why not use the more common command below? Isn't that easier to understand, simpler?

:w ! sudo cat > %

redirected problem

Let's analyze it again, as before, it can be converted into shell commands with the same functionality:

$ cat readonly-file-name | sudo cat > %

This command seems to have no problem at all, but once it is run, another error appears:

/bin/sh: readonly-file-name: Permission denied

shell returned 1

What's going on? Why did he prompt that he did not have permission when he clearly added sudo? The reason is that redirection, which is executed by the shell, will be executed before all commands start, so redirection is not affected by sudo, and the current shell itself is also started as a normal user, and does not have permission to write this file, so there is the above error.

redirection scheme

There are several ways to solve the redirection without permission error, of course, in addition to the tee solution, there is a more convenient solution: open a shell with sudo, and then execute the command containing redirection in the shell with root privileges, such as:

:w ! sudo sh -c 'cat > %'

However, when executed like this, % is not expanded in Vim due to the existence of single quotes, it is passed intact to the shell, and in the shell, a single % is equivalent to nil, so the file is redirected to nil, all contents are lost, and the file is saved.

Since the error is due to % not expanding, try replacing the single quote 'with double quotes "and try again:

:w ! sudo sh -c "cat > %"

Success! This is because % is extended to the current filename before the command is passed to the shell. The difference between single quotes and double quotes can be referred to here. Simply put, single quotes will pass their inner contents intact to the command, but double quotes will expand some contents, such as variables, escape characters, etc.

Of course, you can also map it to a simple command and add it to.vimrc as before:

" Allow saving of files as sudo when I forgot to start vim using sudo.

cmap w!! w ! sudo sh -c "cat > %"

Note: There is no longer a need to redirect output to/dev/null.

The above is "Linux environment VI/VIM editing files without permission to save how to do" all the content of this article, thank you for reading! I believe that everyone has a certain understanding, hope to share the content to help everyone, if you still want to learn more knowledge, welcome to pay attention to the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report