6
zsh=/bin/zsh
sh -c "echo $zsh >> /etc/shells"
sh: /etc/shells: Permission denied

OK, fine. And if I add sudo, it works. Fine.

zsh=/bin/zsh
sudo sh -c "echo $zsh >> /etc/shells"

But if I use open (to add /bin/zsh in /etc/shells manually), then even though I already use sudo, trying to edit the file brings up a dialog window that says that I cannot edit it:

sudo sh -c 'open /etc/shells'

You don’t own the file “shells” and don’t have permission to write to it.

You can duplicate this document and edit the duplicate. Only the duplicate will include your changes.

enter image description here

Why is that? What is wrong with the sudo sh -c 'open /etc/shells' command?

1
  • 2
    @KamilMaciorowski "You asked 'why?'; you did not ask 'how can I get access?'. Then you accepted an answer that answers the latter and does not even try to answer the former." - I agree with your argumentation and have changed the accepted answer to telcoM's. And regarding the "how to get access" question, or rather "how to edit that file", my current approach is to use a command-line editor: personally I like Helix.
    – jsx97
    Commented Aug 14 at 9:01

3 Answers 3

23

The macOS command open command will not actually start the editor on its own. Instead, it asks the macOS Launch Services to do it.

Your login session's Launch Services component runs as your regular user account, and so it cannot launch the editor with root privileges. Using sudo to have the open command make the request with root privileges does not change this fact.

There does not seem to be a way to add an attribute that would effectively say "please start the application that will open this file as root" to the Launch Services request, and even if it was, it seems the Launch Services wouldn't have the capability to run things as root anyway.

6

The sudoedit command (man sudoedit) solves this problem.

First, setup sudoedit:

In your ~/.bashrc, add:

export EDITOR=$(type -p editor_of_choice)
export VISUAL=$(type -p editor_of_choice)

Then source ~/.bashrc.

This completes sudoedit setup.

Then, you can sudoedit /etc/shells.

  1. As root, sudoedit makes a temporary copy of the file-to-be-edited.
  2. As $USER, invokes $VISUAL in the GUI environment, $EDITOR in non-GUI, on the temporary file.
  3. As root, copies the temporary file back to the file-to-be-edited, if the editor succeeded.
5
  • This still won't help if you're trying to use a GUI editor with open.
    – Barmar
    Commented Aug 14 at 14:36
  • 1
    Where is sudoedit from?  It's not installed on this Mac (macOS 12 Monterey), and it's not available in HomeBrew.
    – gidds
    Commented Aug 14 at 21:07
  • Doesn't sudoedit already determine the pathname of the editor command?
    – qqqq
    Commented Aug 14 at 23:33
  • 1
    @gidds sudoedit comes with sudo. But for some reason macOS doesn't include it. The reason may well be that it wouldn't work for many people because anything that invokes a GUI editor would run into the same problem as this question! Commented Aug 15 at 17:35
  • 1
    @Gilles'SO-stopbeingevil' sudoedit doesn't run the editor as root (or whatever the target user is), but as the calling user on a temporary copy of the file, so it would solve the immediate problem here, but not other kinds of problems like the fact that open (assuming it works like xdg-open) is asynchronous (doesn't wait for the editor to terminate). Commented Aug 16 at 7:21
2

I couldn't find anything in the man page explaining this behavior, but I'm guessing that it's resolving who the graphically logged in user is and trying to open the file as that user even when it's wrapped in the layer of sudo execution. That is to say, it's not truly trying to open the file as the root user.

Running graphical commands as sudo is strongly discouraged, so I'm guessing this kind of behavior is intentionally stopping you from doing that.

This thread might help clarify some of the reasons for this.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .