forked from Hardmath123/hardmath123.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sudo.html
216 lines (186 loc) · 10.4 KB
/
sudo.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/base.css"/>
<title>Living Without Sudo - Comfortably Numbered</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
MathJax.Hub.Config({
tex2jax: {inlineMath: [['($','$)']]}
});
</script>
</head>
<body>
<header id="header">
<link rel="stylesheet" href="/octicons/octicons.css">
<script src="static/cheet.js" charset="utf-8"></script>
<script src="static/main.js"></script>
<h1>
<a href="/"><span class="left-word">Comfortably</span><span class="right-word">Numbered</span></a>
</h1>
<!-- You're reading the source to my blog? What do you think?
Do you have dinner plans? -->
</header>
<article id="postcontent" class="centered">
<section>
<h2>Living Without Sudo</h2>
<h4>Friday, November 29, 2013 · 4 min read</h4>
<p class="dropcap">You should not trust me with matches, knives, expensive
cars, and <code>sudo</code>: the command that makes you a god-like user with
root powers. I'm the kind of person who accidentally <code>rm -rf</code>'s his
<em>Desktop</em> (by the way, the sporadically disappearing icons are both
hilarious and mortifying). So whenever I'm asked to <code>sudo</code>
something, I get both worried and suspicious. And over the years, I have
perfected the art of installing things without <code>sudo</code>. You can
follow along this tutorial with just a shell.
<h3>Why sudo?</h3>
<p>The first thing to realize here is that 99% of the time, the only reason we
need to use <code>sudo</code> is to make that program accessible to everyone.
That's it. When you run a UNIX program, you're saying <q>execute this file</q>;
and when you <code>sudo</code> you essentially say <q>everyone can access this
file from everywhere</q>.
<p>For example, suppose I want to install a program called <code>easy</code>
that acts like the classic Staples Easy Button and executes <code>say that was
easy</code> (I actually do have this on my computer, and yes, I use it a lot).
It's not too tough:
<pre><code>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!
</code></pre>
<p>Now I can run my script by typing <code>~/Desktop/easy</code>. But I don't
want to have to type that huge thing each time I do something awesome—I
want <code>easy</code> to be one-step executable just like <code>vim</code>.
This is where <code>sudo</code> comes in.
<p>Bash reads a variable called <code>$PATH</code>, 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 <code>echo $PATH</code>. 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 <code>sudo</code> to make sure you know
what you're doing.
<h3>.profile</h3>
<p>If we could tack on our own directory to the <code>$PATH</code>, we could
dump our junk in there without messing with anything sudo-ey, right? Right. To
modify <code>$PATH</code>, you need another UNIX trick: a file called
<code>~/.profile</code>.
<p><code>.profile</code> 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 <code>.profile</code>: print a friendly message on top of the
Terminal when you start it up, customize your prompt, and mess with your
<code>$PATH</code>.
<p>Since it's a hidden file, you should create it using the command line:
<pre><code>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)</code></pre>
…and you should have TextEdit open up with a blank
<code>.profile</code>. Now we can create our new <code>$PATH</code> by tacking
on <code>~/my_bin</code> to it. Add the following to the <code>.profile</code>:
<code>export PATH=$PATH:~/my_bin</code>. 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 <code>echo $PATH</code> and
see if it changed from last time.
<p>We just told Bash that <code>~/my_bin</code> contains executable files. We
have <em>not</em> created that directory yet, so let's got do that: <code>mkdir
my_bin</code>. And, just for fun, dump <code>easy</code> in there.
<p>Now you can test it out: type <code>easy</code>. If all went well, there
shouldn't be any errors. (If something exploded, feel free to drop a comment
below.)
<h3>Using your powers.</h3>
<p>That's actually all you need. To install a package, download it and look for
its binaries (they will probably in a directory called <code>bin</code>). Alias
the commands you care about to <code>~/my_bin</code>. And then have fun.
<p>If you use Python, you may want to add the following line to your profile:
<code>export PYTHONPATH=$PYTHONPATH:~/my_bin/</code>. This lets you simply copy
Python modules to your <code>~/my_bin</code>. Also take a look at `virtualenv`.
<p>On a Mac, it's worth installing Homebrew this way—almost everything
works when locally compiled with it.
<p>Some packages need configuration files to work right from a foreign
directory. For example, <code>npm</code> needs you to create
<code>.npmrc</code> and add a <em>prefix</em>, or the directory which you want
to isolate all node stuff in. Mine simply reads <code>prefix =
"~/my_bin/node_stuff"</code>.
<p>Finally: if you mess up your profile, you may have unpleasantries with your
terminal (what if you accidentally clear your <code>$PATH</code>? 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
<code>/usr/bin/rm ~/.profile</code>, which will wipe out the profile file, and let
you start fresh.
<p>Good luck, and hack on!
</section>
<div id="comment-breaker">◊ ◊ ◊</div>
<!--
<section>
<center>(<a id="comment-toggle" href="#comment-toggle">Click to load comments…</a>)</center>
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = 'comfortablynumbered';
var disqus_identifier = 'sudo.html';
window.addEventListener(
'load',
(function() {
document.getElementById('comment-toggle').addEventListener('click',
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}),
true);
}),
true
);
</script>
</section>
-->
</article>
<footer id="footer">
<div>
<ul>
<li><a href="http://github.com/Hardmath123">
<span class="octicon octicon-mark-github"></span>
Github</a></li>
<li><a href="feed.xml">
<span class="octicon octicon-rss"></span>
Subscribe (RSS)</a></li>
<li><a href="https://github.com/Hardmath123/hardmath123.github.io/issues/new?title=Hi&body=How's%20it%20going%3F">
<span class="octicon octicon-comment-discussion"></span>
Feedback</a></li>
<li><a href="mailto:contact-at-comfortablynumbered-dot-appspotmail-dot-com">
<span class="octicon octicon-mail-read"></span>
Email me</a></li>
<li><a href="http://creativecommons.org/licenses/by-nc/3.0/deed.en_US">
<span class="octicon octicon-law"></span>
CC BY-NC 3.0</a></li>
<li><a href="appreciation.html">
<span class="octicon octicon-beer"></span>
Other</a></li>
</ul>
</div>
<!--
<span class="sc">ComfortablyNumbered</span> · Hardmath123 (2013) · <a href="feed.xml">RSS Feed</a>
·
<a href="/appreciation.html">
<span class="octicon octicon-beer"></span></a>
<a rel="license" href="http://creativecommons.org/licenses/by-nc/3.0/deed.en_US">
<img
alt="Creative Commons License"
src="http://i.creativecommons.org/l/by-nc/3.0/80x15.png"/>
</a>
-->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-46120535-1', 'hardmath123.github.io');
ga('require', 'displayfeatures');
ga('send', 'pageview');
</script>
</footer>
</body>
</html>