Living Without Sudo
UNIX hacking for the faint at heart, or those blessed with mean sysadmins.
Friday, November 29, 2013 · 4 min read
You should not trust me with matches, knives, expensive
cars, and sudo
: the command that makes you a god-like user with
root powers. I'm the kind of person who accidentally rm -rf
's his
Desktop (by the way, the sporadically disappearing icons are both
hilarious and mortifying). So whenever I'm asked to sudo
something, I get both worried and suspicious. And over the years, I have
perfected the art of installing things without sudo
. You can
follow along this tutorial with just a shell.
Why sudo?
The first thing to realize here is that 99% of the time, the only reason we
need to use sudo
is to make that program accessible to everyone.
That's it. When you run a UNIX program, you're saying execute this file
;
and when you sudo
you essentially say everyone can access this
file from everywhere
.
For example, suppose I want to install a program called easy
that acts like the classic Staples Easy Button and executes say that was
easy
(I actually do have this on my computer, and yes, I use it a lot).
It's not too tough:
echo "say that was easy" > ~/Desktop/easy # create the file "easy" with our contents
chmod +x ~/Desktop/easy # tell your computer that it's ok to execute this file
~/Desktop/easy # run it!
Now I can run my script by typing ~/Desktop/easy
. But I don't
want to have to type that huge thing each time I do something awesome—I
want easy
to be one-step executable just like vim
.
This is where sudo
comes in.
Bash reads a variable called $PATH
, which contains a list of
various directories separated by colons. When you type a command on the shell,
Bash searches each of these directories for that file, one by one. You can see
this list right now with echo $PATH
. These directories contain
important system files, and are accessible by everyone. So it makes sense not
to let mortals like me to mess with them. When you install a package, most of
the time you're just moving the script files to one of these directories so
it's easy to run, and Bash asks you for sudo
to make sure you know
what you're doing.
.profile
If we could tack on our own directory to the $PATH
, we could
dump our junk in there without messing with anything sudo-ey, right? Right. To
modify $PATH
, you need another UNIX trick: a file called
~/.profile
.
.profile
is another script file that's executed before your
shell loads, so that you can customize it. The dot in front makes it invisible
to Finder, so you can only mess with it using a shell. You can do all sorts of
neat things with .profile
: print a friendly message on top of the
Terminal when you start it up, customize your prompt, and mess with your
$PATH
.
Since it's a hidden file, you should create it using the command line:
cd ~/ # go to your home directory
touch .profile # create the file
open -a TextEdit .profile # open with TextEdit (you can also use pico/vim/emacs)
…and you should have TextEdit open up with a blank
.profile
. Now we can create our new $PATH
by tacking
on ~/my_bin
to it. Add the following to the .profile
:
export PATH=$PATH:~/my_bin
. Save, and quit; and then refresh your
Terminal (you can just close this window and open a new one). This forces the
profile to be run. If you want a sanity check, try echo $PATH
and
see if it changed from last time.
We just told Bash that ~/my_bin
contains executable files. We
have not created that directory yet, so let's got do that: mkdir
my_bin
. And, just for fun, dump easy
in there.
Now you can test it out: type easy
. If all went well, there
shouldn't be any errors. (If something exploded, feel free to drop a comment
below.)
Using your powers.
That's actually all you need. To install a package, download it and look for
its binaries (they will probably in a directory called bin
). Alias
the commands you care about to ~/my_bin
. And then have fun.
If you use Python, you may want to add the following line to your profile:
export PYTHONPATH=$PYTHONPATH:~/my_bin/
. This lets you simply copy
Python modules to your ~/my_bin
. Also take a look at `virtualenv`.
On a Mac, it's worth installing Homebrew this way—almost everything works when locally compiled with it.
Some packages need configuration files to work right from a foreign
directory. For example, npm
needs you to create
.npmrc
and add a prefix, or the directory which you want
to isolate all node stuff in. Mine simply reads prefix =
"~/my_bin/node_stuff"
.
Finally: if you mess up your profile, you may have unpleasantries with your
terminal (what if you accidentally clear your $PATH
? Bash won't
find any executables whatsoever…). To fix this, always remember that you
can reference a command from its full path. Your last resort should be
/usr/bin/rm ~/.profile
, which will wipe out the profile file, and let
you start fresh.
Good luck, and hack on!