When I want to vimdiff root files, I use the following alias, as per this suggestion.

alias sudovimdiff='SUDO_EDITOR=vimdiff sudoedit'

I can then use the following command.

$ sudovimdiff /root/a /root/b

However, if one of the files is writable by my user, the command fails.

$ sudovimdiff /root/a /tmp/b
sudoedit: /tmp/b: editing files in a writable directory is not permitted

Is there a way to vimdiff one root and one non-root file, using my user's environment settings (i.e. sudoedit)?

  • I'm missing something. Why can't you just copy the file? Or do you mean a file that's only readable by root? – Wildcard Jan 10 '18 at 4:41
  • @Wildcard I quote the error above, but it causes an error with files in a writable directory. Apparently it relates to security issues. – Sparhawk Jan 10 '18 at 6:16

May be useful related to that sudoedit error message:

sudoedit: ... editing files in a writable directory is not permitted

Please try a modification to sudoers file using sudo visudo, add a line:

Defaults  !sudoedit_checkdir

More here.

  • This works perfectly! Can you think of any negatives to making this option unset? – Sparhawk Jul 5 '18 at 12:55
  • No exact stance, nor idea why things changed about 2016. I didn't see that error before that. – ajaaskel Jul 10 '18 at 13:34

From man sudo, in the part describing -e (aka sudoedit):

 To help prevent the editing of unauthorized files, the
 following restrictions are enforced unless explicitly allowed
 by the security policy:

 ·   Symbolic links may not be edited (version 1.8.15 and

 ·   Symbolic links along the path to be edited are not
     followed when the parent directory is writable by the
     invoking user unless that user is root (version 1.8.16
     and higher).
 ·   Files located in a directory that is writable by the
     invoking user may not be edited unless that user is root
     (version 1.8.16 and higher).

So, either:

  • we invoke sudoedit as root, which would defeat the purpose or
  • we copy the user's file to new directory not editable by the user:

    mkdir /tmp/foo
    cp /tmp/b /tmp/foo
    chmod a-w /tmp/foo
    sudoedit /root/a /tmp/foo/b
  • we edit the root file and diff it inside:

    sudoedit /root/a
    # in Vim
    :vert diffsplit /tmp/b
  • since sudoedit treats all non-sudo arguments filenames, you could use a wrapper script:

    $ cat foo.sh
    #! /bin/sh
    exec vimdiff "$@" "$DIFF_FILE"
    $ SUDO_EDITOR ="$PWD/foo.sh" DIFF_FILE="$PWD/.zshrc" sudoedit /etc/zsh/zshrc
    [sudo] password for muru:
    2 files to edit
    sudoedit: /etc/zsh/zshrc unchanged
  • Thanks muru (+1). I think the last version is the least fiddly, although it'd be nice to specify both files with the initial command. I tested vim's -c <command>, but sudoedit won't take that. Presumably there are no other options? – Sparhawk Jan 10 '18 at 6:19
  • @Sparhawk sudoedit treats all arguments as filenames, so the only way to pass on options to Vim via sudoedit would be to write a wrapper script. So as long as you have to specify a user-editable file, this would be a problem. See update for a possible wrapper script. – muru Jan 10 '18 at 6:30
  • Gosh, that's pretty clunky, too. I think the third is still probably easier. Looks like it can't be done in a simple fashion, so I'll accept this answer, unless anything else comes along. Cheers. – Sparhawk Jan 10 '18 at 6:32
  • 1
    @Sparhawk you're using an alias anyway, so you can wrap the 4th method in a function instead: sudodiff () { SUDO_EDITOR="/path/to/foo.sh" DIFF_FILE="$2" sudoedit "$1"; }. Then the only clunky part is creating the wrapper script for first use. – muru Jan 10 '18 at 6:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.