2

I was following this tutorial - http://howtonode.org/introduction-to-npm - and set /usr/local to $USER, which I now realise was a huge mistake.

Does anyone know how I can revert these changes, but still allow Homebrew, Node, Ruby, etc to install without requiring sudo?

0
12

As for the first part of your question, you can't revert the changes, there's no Z or undo command, but you can set the permissions to a good guess of what it was before. More on this in the first bullet below.

To install software in /usr/local you must have write permissions in the directory (and its subdirectories). There are several ways to achieve this:

  1. Set the owner to yourself. That's what you did with sudo chown -R $USER /usr/local. My Linux sysadmin background tells me this is not the standard way, because /usr/local is outside your home directory and shouldn't be owned by you. But I wouldn't say you damaged anything irreparably.
  2. Use sudo, but you don't want to be required to use it.

    (From my point of view the best solution. Why? sudo protects you from yourself. You think twice if you need to type sudo (unless you are following a tutorial from http://howtonode.org :-) ).)

  3. Set ACLs. Nice way to separate the original permissions from your added permissions. (See http://en.wikipedia.org/wiki/Access_control_list for more info on ACLs.)
  4. Configure groups. Add yourself to the group that owned /usr/local and change permissions to g+rwx/g+rw. Cumbersome. Don't do that.

You did 1. and want to revert the changes, 2. you don't want, and I don't recommend 4., so I'll explain 3.:

  • Let's first "revert" the changes you made. /usr/local was probably owned by user root, group wheel. You can set it as follows:

    $ cd /usr/local
    $ sudo chown -R root:wheel .
    
  • Set the ACLs so that you have all permissions:

    $ cd /usr/local
    $ sudo chmod -R +a "$USER allow delete,readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown,list,search,add_file,add_subdirectory,delete_child,file_inherit,directory_inherit" .
    

    (see man chmod, section ACL MANIPULATION OPTIONS for details.)

  • You will see that all files have a + appended, ls -e shows the ACLs:

    $ cd /usr/local
    $ ls -la .
    total 0
    drwxr-xr-x+ 11 root  wheel   374 Oct 10 21:57 .
    drwxr-xr-x+ 12 root  wheel   442 Sep 22 13:44 ..
    drwxr-xr-x+  3 root  wheel  3774 Oct 10 21:57 bin
    -rw-r--r--+  1 jaume wheel    0  Oct 25 14:53 myACLtestfile
    drwxr-xr-x+  3 root  wheel   136 Jul 26 18:55 include
    drwxr-xr-x+  4 root  wheel   442 Jul 26 18:55 lib
    (...)
    $ ls -led bin
    drwxr-xr-x+ 3 root  wheel  3774 Oct 10 21:57 bin
     0: user:jaume allow list,add_file,search,delete,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown,file_inherit,directory_inherit
    $ ls -le myACLtestfile 
    -rw-r--r--+ 1 jaume  wheel  0 Oct 25 14:53 myACLtestfile
     0: user:jaume inherited allow read,write,execute,delete,append,readattr,writeattr,readextattr,writeextattr,readsecurity,writesecurity,chown
    

(I've tested the commands above, but I may have made a typo. As best practice I recommend that you run the commands above in a test directory. You could do mkdir ~/tmpacl. Then cd ~/tmpacl and sudo rsync -av /usr/local/ . to copy the contents of /usr/local to ~/tmpacl. Then skip cd /usr/local in every section above to apply the commands to ~/tmpacl. When you are done, rm -rf ~/tmpacl.)

Now you can install software (or do anything, for that matter) in /usr/local without sudo.

Notice that any file you create in /usr/local will belong to you (as myACLtestfile in the listing above), so you will see that some files are owned by root and others by you.

(If you change your mind and want to go back to the wonderful world of sudo, delete the ACLs as follows:

sudo chmod -R -N /usr/local

and set permissions to root:wheel:

sudo chown -R root:wheel /usr/local

)


** EDIT **

If the setup routine of the software you want to install uses /usr/bin/install this may be a much simpler solution. Add:

alias install="sudo /usr/bin/install"

to ~/.bashrc. Then do . ~/.bashrc for changes to take effect.

Then edit /etc/sudoers with command sudo visudo, add:

<your username> ALL=(ALL) NOPASSWD:/usr/bin/install

and save and close the file with :x.

(If you use other install command elsewhere in the filesystem, like GNU install, change the path above appropriately.)

For this to work the software must use /usr/bin/install. This is usually the case with make install.

** /EDIT **

2
  • What a great answer, I wish I could vote you up twice!
    – JamiePatt
    Oct 25 '12 at 13:07
  • @Matty F: I've added a much simpler way to achieve "sudo-less" installation (condition: /usr/bin/install must be used), please check it at the bottom of my answer.
    – jaume
    Oct 26 '12 at 7:00
2

Boot to your recovery HD and see whether you want to use terminal to fix the Mac HD /usr/local by hand or if you'd rather just restore from a convenient backup.

Since Macs don't need anything to exist in /usr/local I don't see how sudo or anything system critical is even affected so perhaps I am not even understanding your situation.

Remove everything from /usr/local and start over is often a good plan for your local command-line content to get set up properly if you can’t clean/repair it piecemeal.

0

node without sudo

Here's the easiest way to install Node.js

  • without sudo or root
  • without any changes to system permissions
  • without a package manager
  • from Official Node.js builds, through the release API

https://webinstall.dev/node

Example:

curl -s https://webinstall.dev/node@stable | bash

Others

There are ways to install ruby and python without root, but after battling both I couldn't figure out a generic solution that would work without having lots of toolchain.

brew... makes me sad in this regard. I don't see any reason why they chose to muck with system permissions... other than that perhaps they're not smart enough to figure out a nice way to get things like ruby and python to play nice either.

I'd love to see a better solution.

If I figure it out, I'll PR it to webi.

Fixing permissions

I have nothing to add apart from what others have said, but I'll include this for completeness.

To switch to user-level permissions:

sudo chown -R "$(whoami)":admin /usr/local
# Or possibly 'staff' instead:
# sudo chown -R "$(whoami)":staff /usr/local

Or to change back to what it was before:

sudo chown -R root:wheel /usr/local
4
  • Please reread the question. It‘s not about installing node, it‘s about fixing ownership issues on /usr/local.
    – nohillside
    Jul 12 '20 at 6:34
  • 1
    @nohillside I think that you may have only seen the title and not seen the question in the user's post "Does anyone know how I can revert these changes, but still allow Homebrew, Node, Ruby, etc to install without requiring sudo?"
    – coolaj86
    Jul 13 '20 at 3:38
  • The main part of your anwer is about promoting your own solution which only installs node for the current user (not system-wide as Homebrew does). There might be use cases where this is enough, but it isn't a general solution.
    – nohillside
    Jul 13 '20 at 6:05
  • @nohillside Well, then it sounds like you're just here to promote your own biases and that you didn't actually investigate the problem or the solution, and don't actually care whether or not people who view this get a well thought out solution that solves the exact stated problem.
    – coolaj86
    Jul 13 '20 at 6:15

You must log in to answer this question.

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