79

A lot of the time I edit a file with nano, try to save and get a permission error because I forgot to run it as root. Is there some quick way I can become root with sudo from within the editor, without having to re-open and re-edit the file?

Kusalananda
  • 333,661
Kit Sunde
  • 4,504
  • 10
  • 31
  • 34
  • merging with this question has been suggested. Basically the same problem, but vim. I'm considering the merge... though I'm also considering the fact that vim specific instructions will not work in nano. – xenoterracide Apr 24 '11 at 08:50
  • 1
    @xenaterracide - I think the vim question is a special case of this one, since that one actually has a solution and it seems the general case has none. I'm not sure either though, up to you. :) – Kit Sunde Apr 24 '11 at 09:44
  • You can make a mapping in your .vimrc to easily call the sudo tee function:
    " Allows writing to files with root priviledges
    cmap w!! w !sudo tee % > /dev/null
    – jasonwryan Apr 25 '11 at 07:51
  • @xenoterracide: Caleb's answer about Nano is useful, so I think we should keep this one only about Nano. – Mikel Apr 25 '11 at 08:15
  • 1
    @mikel I decided that merging is invalid. nano is not vim... and no nano solutions that are similar to vim's have presented themselves. – xenoterracide Apr 25 '11 at 08:16

5 Answers5

56

No, you can't give a running program permissions that it doesn't have when it starts, that would be the security hole known as 'privilege escalation'¹.

Two things you can do:

  1. Save to a temporary file in /tmp or wherever, close the editor, then dump the contents of temp file into the file you were editing. sudo cp $TMPFILE $FILE. Note that it is not recomended to use mv for this because of the change in file ownership and permissions it is likely to cause, you just want to replace the file content not the file placeholder itself.
  2. Background the editor with Ctrl+z, change the file ownership or permissions so you can write to it, then use fg to get back to the editor and save. Don't forget to fix the permissions!

¹ Some editors are actually able to do this by launching a new process with different permissions and passing the data off to that process for saving. See for example this related question for other solutions in advanced editors that allow writing the file buffer to a process pipe. Nano does not have the ability to launch a new process or pass data to other processes, so it's left out of this party.

Caleb
  • 70,105
  • Excellent. Thanks Caleb. I just ran into this problem about 30 minutes ago. :) – boehj Apr 23 '11 at 18:33
  • 2
    @Caleb You can use the tee command from within vim to do what you describe: :w !sudo tee –  Apr 24 '11 at 16:41
  • @hellojesus Brilliant trick. If you care to write that up as an answer I can remove it from mine. I figure people other than nano users get into this situation and may find themselves here. – Caleb Apr 25 '11 at 06:14
  • 6
    This question is supposed to be about nano. If we start including answers about Vim here, what's the point of this question? We already have Becoming root from inside Vim for Vim. – Mikel Apr 25 '11 at 08:13
  • Great related link Mikel. I've edited again to just link to that set of answers instead of getting off topic here. – Caleb Apr 25 '11 at 08:24
  • cat TMPFILE > FILE will obviously need you to do su - or similar first. sudo cp TMPFILE FILE would be easier. cp actually truncates the file if it already exists and doesn't change it's permissions. – Mikel Apr 26 '11 at 01:04
  • @Caleb: The related link was actually suggested by xenoterracide. – Mikel Apr 26 '11 at 01:51
  • @Caleb whenever I look for an answer regarding bash, I always see your answers :D – user1754665 Feb 24 '17 at 15:58
  • 2
    Save to a temporary file in /tmp - How to save to temp file while inside nano ? – Anand Rockzz Apr 23 '18 at 07:03
  • @user6908 +1 but the correct command to use with vim is :w !sudo tee % – baptx Nov 16 '18 at 21:31
  • No, you can't give a running program permissions that it doesn't have when it starts, that would be the security hole known as 'privilege escalation'¹. -- is it still privilege escalation if root password is required before the running program is given permissions? – Joker Apr 15 '23 at 13:15
  • @Joker Yes, it doesn't work like that. If something asks for and verifies root password and then grants root permissions, that think itself must me already running as root, and to "give" extra permissions to something else it usually means it spawns that think with the verified priv level. – Caleb Apr 19 '23 at 12:08
10

I just tried nano, and what I found most surprising is it doesn't even warn you that the file is read-only when you start trying to edit the file. (UPDATE: Apparently nano 2.2 does warn; 2.0 doesn't.)

Here's a (basic) script that does that.

It checks if you can edit the file, and if you can't, it runs "nano" as root instead.

/usr/local/bin/editroot (or ~/bin/editroot)

sudo=                       # empty is false, non-empty is true
editor=nano                 # XXX check $EDITOR and $VISUAL

if test -e "$1" && test ! -w "$1"; then if test -t 0 && test -t 2; then printf "%s is not writable. Edit with sudo? [y/n] " "$1" 1>&2 read -n 1 case $REPLY in y|Y) sudo=true ;; n|N) sudo= ;; *) printf "\nExpected y or n. Exiting.\n" 1>&2 exit 1 ;; esac else printf "%s is not writable. Fix the permissions or run "view" instead." "$1" 1>&2 exit 1 fi fi

${sudo:+sudo} "$editor" "$1"

And a command I called view so that you can avoid the prompt if you know you aren't going to make any changes.

/usr/local/bin/view (or ~/bin/view)

editor=nano
readonlyflag=-v

"$editor" $readonlyflag "$1"

There's already a program called view that's part of Vi/Vim, so feel free to suggest a better name.
(But I think a full implementation of this program would make Vi's view redundant.)


Full versions

Mikel
  • 57,299
  • 15
  • 134
  • 153
  • 1
    It does actually warn you. Question would then be which version you are using. Also, on Debian-based systems the alternatives system is better suited for what you are suggesting. – 0xC0000022L May 06 '11 at 22:25
  • 3
    For your reference: [ Read ... lines (Warning: No write permission) ] is what appears right above the two lines of help for the shortcuts (bottom of the screen). Nano version is 2.2.4. – 0xC0000022L May 06 '11 at 22:28
  • Ah, it doesn't warn in nano 2.0, which is what I was testing with. – Mikel May 06 '11 at 22:38
  • cool we sorted that out :) – 0xC0000022L May 06 '11 at 22:44
  • The entire repo of scripts is a treasure trove of functionality I didn't know I needed. Thank you @Mikel. – John Mansell Dec 13 '22 at 23:14
1

The ability to filter text from nano to an external command was added in release 2.9.8 (2018).

Filtering the buffer's text through an external command makes it possible to filter the current buffer through sudo tee some/path/file. This will save the text to some/path/file as root, provided you have access to sudo.

To do this in the editor, press ^R^X, i.e., Ctrl+R+Ctrl+X, and then type

|sudo tee some/path/file

This will overwrite some/path/file as root.

Note that it may be safer to abandon the current edit session and re-open the file with sudo nano some/path/file as you then don't have to rely on typing the full pathname correctly but instead may rely on the shell's filename auto-completion functionality.

Kusalananda
  • 333,661
0

I took this approach... I can use less if I want to view a file... So i block myself from opening unwritable files with nano.

function nano () {
  if [ ! -f "${@: -1}" ] || [ -w "${@: -1}" ]; then
    /bin/nano $@
  else
   echo "Write permission is NOT granted on ${@: -1}"
  fi
}
Ray Foss
  • 1,002
  • Don't forget to quote the expansion of "$@" on nano's command line, otherwise it breaks for files with spaces in their names. – Peter Cordes Apr 26 '22 at 07:03
0

Short answer (but please read the details):

  1. With the file open in the editor
  2. Go to a separate terminal/bash session
  3. Back up the original file
  4. Run f=forgotsudo.oops; cd ~; [ -e $f ] || mkfifo $f; sudo sh -c "cat $f >> [filename]"; rm $f
  5. In your editor, save the file to ~/forgotsudo.oops, which will append the context to the original file as sudo

The process, while seemingly complicated, can pretty much be handled in a one-liner.

And can definitely be scripted for reusability if you find yourself doing it often.

More Detail:

I'd appreciate some experienced eyes on this to validate it, as it's my first try at what I believe is a novel solution. I really wasn't expecting it to work at all, since I'd never seen it mentioned before. If it turns out to be a horrible idea for some reason I haven't thought of, I'll delete it.

It seems to me that it could be wrapped up in a script (forgotsudo) and made even more robust.

The advantage of the fifo method is that it should work from pretty much any editor, regardless of whether the editor can filter through an external command.

Long form explanation:

After you try to save the file (for example, /etc/abcdef.conf) and realize that you forgot to sudo, open another terminal (or tmux windows, etc.) and, from Bash:

sudo cp /etc/abcdef.conf /etc/abcdef.conf.bak # back up the original file
cd ~ # or somewhere with write permissions
mkfifo forgotsudo.oops
sudo cat forgotsudo.oops >> /etc/abcdef.conf ; rm forgotsudo.oops

While the fifo is appending to the real file, switch to the editor and save the buffer to ~/forgottosudo.oops using the normal "save" technique for your editor. E.g.:

  • In Vim, :w! ~/forgotsudo.oops
  • In Nano, Ctrl+O, change the filename to ~/forgotsudo.oops, select Y to save to a different filename, and Y again to confirm the "overwrite".

Note that, in this case, the modified buffer will be appended to the original file. You can then exit the editor, re-edit the file as sudo, and remove the "duplicate" original. This assumes, of course, that the file is not in use by some process that will "choke" on the duplicated contents.

If it is a file that is sensitive to "bad data", you can also, of course, use a single > to overwrite the existing file with the new contents. However, note that the original file contents will be destroyed as soon as the sudo cat ... is executed. If you lose the buffer in the editor for any reason, the file will be destroyed/emptied. Definitely make a backup.

Side note: With either an overwrite or append, the original file permissions are left intact after the save.

NotTheDr01ds
  • 3,547