After a year working at a Rails shop that deploys to Heroku, I decided it's time to learn some sysadmin basics. Here are some things I've done the past couple months that might give other noobs some ideas.
- Make aliases for most Linux commands. Abstract Linux into a simple interface of aliases that you can browse in your .zshrc/.bashrc/fish.config. Linux becomes much more enjoyable when you can type `untar <file>` instead of remembering the magical incantation `sudo tar -xzvf <file>`. Make aliases for everything. nginx-reload. nginx-restart. alias z="vim ~/.zshrc && source ~/.zshrc". I even abstract apt-get commands into ag-install, ag-update, ag-remote, etc.
- Use dropbox cli, a shared folder with dotfiles, and symlinks to keep dotfiles synced between your server(s) and laptop(s).
- Install tmux on it so that you can `$ tmux attach` to a persistent shell so that things still run when you close your remote connection and they're still there when you log back in.
- Run weechat (terminal irc client) in tmux so that you never have to log out of irc again.
- Learn how to rsync up and down files from your server.
- rsync your Sinatra app (or whatever) onto your server and run it on port 5000, immediately see it live.
- Install nginx and have your VPS serve multiple domain names, each domain name pointing to a Sinatra app running on port 5000, 5001, and 5002.
- Run each website in its own tmux tab. At the beginning it's easier to reason about a foreground process than some daemonized process.
- Install postgres or whatever database you use to your VPS. Get your db-driven app to connect to it. Connect to your remote db using your favorite db gui.
- Take notes of all the commands you use to set up each component so that you can refer to them later, see how you might have messed up.
- Learn enough bash/zsh/fish to automate all of those commands. Polish it enough so that you can curl your script from a Github gist on a fresh VPS and it will set up your entire environment.
- Install `htop` as a nice overview of your server's stats and the processes that are running. Run it in another tmux tab. My tmux right now has a tab for weechat (irc), tabs for my Clojure apps, and an htop tab. On Friday nights I pretend I'm NASA mission control.
- Learn how to use the `ssh` command to reverse tunnel a connection from your VPS to an app you're running on your local machine for a fast development feedback loop.
- Learn how to use your VPS to encrypt your connection when you're working at coffee shops.
I'm still a noob but I leveled up considerably from this quest arc. I highly recommend.
I still don't have a raging clue about most of Linux, even stuff like what all the folders are supposed to be for: /var/opt /etc/www /usr/local /usr/shared/local ... etc. and why files go the places they go, but it's all an iterative process.
Email me (profile) if you need help with any of the bullet points. I am trying to shape it into a more helpful blog post to share with other noobs.
>- Make aliases for most Linux commands. Abstract Linux into a simple interface of aliases that you can browse in your .zshrc/.bashrc/fish.config. Linux becomes much more enjoyable when you can type `untar <file>` instead of remembering the magical incantation `sudo tar -xzvf <file>`. Make aliases for everything. nginx-reload. nginx-restart. alias z="vim ~/.zshrc && source ~/.zshrc". I even abstract apt-get commands into ag-install, ag-update, ag-remote, etc.
One problem with this is you become a cripple when you have to use an outside machine or need to write a script for wide distribution.
I find that it's the opposite for me since my needs are so simple and I'm not logging hours into Linux cli every day. I simply don't use the VPS cli enough to retain everything and that just makes it frustrating. It's more like Billy's First VPS Side-project rather than a roadmap for industrial-grade sysadmin skills which I'll probably never have.
Aliases become a self-documenting interface. Using my aliases, getting exposed to them every time I add a new one, tweaking them, and simple browsing them from time to time is what helps me remember commands.
It saves me brain cycles sort of like buttons on a GUI.
For me, the alternative to writing an `untar` alias isn't that I remember `tar -xzvf` but that I have to google it every time (or scroll through dozens of possible flags in the man page). I'm not untar'ing things every day.
Now multiply that example across all sorts of commands. I never remember the right flags to `stat`. or `column -nts: /etc/passwd` just to quickly see users.
I won't remember that I like the `--show-upgraded` flag sent to `apt-get upgrade` every time. I don't remember that my nginx conf and websites are in `/etc/nginx/` while their static files are in `/var/www/`. When life gets busy and it's a month since my last VPS login, I'll remember my own `disk-space` abstraction instead of `df -h`.
Finally, I'm not a sysadmin. I don't find myself on random machines nor am I writing scripts for wide distribution. When I spin up a new VPS, I curl a gist that even installs fishshell and then bootstraps the rest of my niceties with fish scripts. If I'm lazy, I'll just wget my .bashrc aliases. If I'm even lazier, I'll just curl it like it's a manpage and browse my abstractions. Not much different than using manpages directly.
But actually over time it turns out that I end up remembering what many of these aliases represent.
The concern you are responding to here was my initial reaction, but I think you've changed my mind.
I like this a lot. Not only do you gain experience using commands by setting up your aliases, but you now have a reference for the future and are learning the commands by repetition; exposing yourself to the config during tweaks.
Add in the use of apropos to find appropriate commands (without googling) and learn to use the search feature while viewing a man page (/[STRING] same as vim!) and you're golden.
>For me, the alternative to writing an `untar` alias isn't that I remember `tar -xzvf` but that I have to google it every time (or scroll through dozens of possible flags in the man page). I'm not untar'ing things every day. //
I set up a permanent history and then for important actions I comment them then just use a script "$ hs keyword" to find what I'm after.
Mind I used to use slackware so "tar xzvf package.tgz" became second nature.
> "Linux becomes much more enjoyable when you can type `untar <file>` instead of remembering the magical incantation `sudo tar -xzvf <file>`."
I love aliases as well, but I remember the particular command for tar extraction (tar xzf) via the mnemonic "eXtract Zee Files" said with an overly stereotypical German accent in my mind. Silly, I know, but I have never forgotten it since.
I have heard people say this before, and it always makes me wonder. Why not remember it as "extract zipped file" instead of "extract zee file"? That is after all a more accurate description of the flags you are giving tar, z indicating that the tarball had been gzipped. You can also specify j for bz2, and J for xz (sorry I don't know any cute sayings for that).
Of even more interest to you is probably that with modern version of GNU tar, you can just say tar xf filename, and then tar will automatically determine whether it should use gzip, bzip2, or xz based on the filetype. So you can save yourself an extra letter there.
Silly/ridiculous references can be easier to remember with less repetition of use (to me at least). The more literal meaning might be more straight forward, but the more absurd one imprints on the mind easier at times. One of the silliest (but effective) examples I've seen is for identifying the songs/calls of birds[1]. Bird calls tend to be kind of abstract to classify, but if you can match them up to a silly mnemonic, they're pretty easy to remember (for me at least).
I think everyone encounters at least a few in school.
I understand what you are saying but it just seems a little silly to me when the "silly mnemonic" is exactly the same as the "actual meaning" except for the word associated with one letter -- xzf meaning extract zee file instead of extract zipped file.
To relate with some of the examples you provided, it would be like remembering the order of operations PEMDAS by remembering
Parentheses, Exponents, Multiplication, Division, Addition, Sally.
I said 'eXtract Zee Files' in the overly stereotypical German accent before even finishing your sentence saying that you did it as well (And I said it out loud, not in my mind).
But more on context - that's actually a great mnemonic. Silly me, just memorizing things.
Instead of renting a VPS, you could also purchase a Raspberry Pi for about $35, and get the same learning experience. In addition to that, the visibility of the cute blinking LEDs (in a transparent case) gives an opportunity for actual "RELAXEN UND WATSCHEN DER BLINKENLICHTEN" and the joy of actually owning "EIN KOMPUTERMASCHINE FÜR DER GEFINGERPOKEN UND MITTENGRABEN".
Edit: the all caps is only because they are quoted verbatim from a famous blackletter sign in university computer rooms in mangled mock German.
I agree in principle, but what you should really be writing are shell functions. Aliases are defined once and cast in stone - if there is a variable in an alias body, it will be evaluated once, on alias creation, and never again. Functions have no such problem. They also let you select process arguments, while aliases delegate this to invoked commands. Aliases are for very simple things, anything more complicated and you should write a function.
Also, you should set up a decent autocompletion. Zsh needs a bit of configuring and fish has it by default - the need for most aliases is eliminated by autocompletion and history functionalities of a shell. There is standard CTRL+R combo which lets you search your history and there is a "up-line-and-search" action in zsh which searches the history for lines starting with what you have on your current line. Set your HISTSIZE to some huge number and never worry about forgetting how to do something or having to repeat (as in re-type) a command.
Use fasd (https://github.com/clvv/fasd). A simple little script that records all paths, files and directories, you visit and sorts them by "frecency" (both frequency and recency). It let's you just `z pr 5` to `/usr/home/you/project/something/test5`. Give it a day and you'll never want to get back.
Yeah, that's true. My bullet point wasn't a very good one-liner.
Aliases are nice because they're the most entry-level customization yet they solve the #1 thing I spent my time doing at the very beginning: hunting down magical incantations on google. When I found one that helped me immediately, I'd collect it in my .bashrc like a pokeball. I had a lot of teeth to cut before I started looking for solutions that were solved with functions.
However, autocompletion based off history is a volatile convenience to me, not something that I feel obviates the need for aliases. Depending on ctrl-r to find `tar -xzvf` isn't much different than autocompleting your own `untar` alias. Except that when `tar -xzvf` isn't in your history anymore as a noob (fresh VPS/fresh shell/different computer), then you're back on Google/manpages to find the incantation so that it's in your history once again.
Besides, here's a simple example of the sort of abstractions I'm talking about:
I type "trans" and then hit tab. All my Transmission-Daemon related stuff is right there ready for autocompletion. I don't have to think about files or locations or paths. I don't have to remember that transmission-daemon is set up as a service. And I especially don't have to remember that its config is a .json file named 'settings' in `/etc/transmission-daemon/`.
While aliases may be great for saving time typing, you can use them to steal from yourself the opportunity to learn how unix commands like 'tar' work. Frankly, tar should never seem like an "incantation", because most of the flags are there as shortcuts. From your example, -f and -z are shortcuts for certain pipes and redirects. 'tar -xzvf file.gz' is equivalent to 'zcat file.gz | tar -xv'; and of course the -v is unnecessary so you have 'zcat file.gz | tar x', which is a lot clearer than 'untar', which won't work for tar.bz2 files, or even plain old .tar files (but, just switch zcat to bzcat and you're golden).
I feel like everyone who has responded to me so far plugged that coax cable from The Matrix into the back of their brain stem one day and just downloaded Everything Unix. I don't really relate to a single comment.
I call it an incantation because you're on your couch eating a frozen meal at 7:30pm on a Tuesday night with your laptop in front of you. The TV is on, but it's muted so it sits in the limbo between a social coping device and a distraction for the few hours you have between the commute from work and bedtime.
Yeah, one day you want to learn more about Unix and tar and how electrons flow on a circuit board and maybe what gravity is -- like, what it really is --, but tonight you just want to get nginx set up for the first time on your linode so it can serve your hand-rolled blog and move the needle just enough so you feel like you're making some progress in life.
You've managed to use `wget` to download nginx-1.2.9.tar.gz onto your VPS. And all you want to do next is get the files out of tar.gz. You'd love to right click it and select "Uncompress" from a context menu, but it's in a terminal window.
For now you just google "ubuntu uncompress tar", click the first result, and copy the incantation into .bashrc aliased to `untar` for future reference before pressing forward into the abyss.
I have to disagree here: knowing the actual commands and their arguments is far more valuable than the small amount of typing saved. Read the man page every time you use the command if you have to, but at least you'll know why `tar zxf` failed on that .tar.bz2 file.
As other commenters have mentioned, relying on aliases leaves you feeling crippled when working on systems that don't have them. If you're repeating commands often enough that you'd like an alias like nginx-reload for them, consider using your shell's history feature instead.
I also make a point of changing the prompt color on each of my systems, because it's much more obvious than reading the prompt for the $host entry.
I agree with you. I just want to point out that these days `tar xf` works for both .zip and .bz2 files (it recognizes the file type automatically). AFAIK it works with both GNU and BSD tar.
Harder since you need to install unpack (it's not installed by default on many installations). Also, "tar xf" has literally the same number of characters, so no hard at all.
I fail to see which of those things require a VPS. You could easily do them from having a local Linux install, or even a Linux VM.
It sounds more to me like you are saying every developer should gain experience working in a Linux environment, a sentiment I would agree with, but there are easier (and cheaper) ways of using Linux than renting a VPS.
Wow, this is a great approach you've chosen, and it will teach you a ton. If you want to start learning more about how your machine is configured, the Nemeth book is very good:
The dropbox thing is a fun experiment, especially when the dotfiles folder is a git repo that sits in dropbox. It saves me from the git commit/push/pull loop when my dotfiles are in flux.
I can add a fish shell function on my laptop and when I switch back to my VPS shell, the function is already loaded and available.
The git repo reminds me what changes I've made today and lets me formalize the changes I've made into commits.
That's a good point that made me think for a second.
In the end, even if I go back to Heroku, I'll have gone from Heroku -> VPS -> Heroku. But it's not full-circle or back-pedaling like it first appears. Rather, I've traded Heroku as a blissful crutch for Heroku as an automator of things I now know how to do.
The pain just means you're ready to reach the next abstraction because you've beat the level and paid your dues.
The reason you have so many people replying saying that your shortcuts are a crutch is because you and I belong to a different group of people than they do.
Allow me to expand.
Unix people are conformists. By "unix people" I mean people that defend Unix constantly.
Quick evidence that they are conformists: "where's Plan 9?"
More evidence: unix utilities have the same crappy interface they had when they were created.
Think about this: Unix is based on the idea that programs should talk to each other via text (strings).
Do you know of anything less structured than a string? A string is a bunch of bytes next to each other. And I don't mean that in a "well, look at how the computer represents it" kind of way (where everything is a bunch of bytes next to each other); I mean that a string is literally the representation of bytes next to each other.
When you call a utility on the command line, say tar, and pass it zxcfvg or whatever that crap is, then pass it a filename, there's no structure here. The program 'tar' is receiving a big string containing what you just wrote: "tar zxcfvg filename.tar.gz". In fact, even more moronically, you receive that data already cut up in pieces as an array, so: ["tar", "zxcfvg", "filename.tar.gz"]. Which means you actually were passed information that is worse than a string since you've now lost information (the spaces). Wow, thanks, Unix, for splitting a string on its spaces. Real handy.
Unix believes on this very flawed idea that strings are a good data structure.
Remember Tcl? It was great. Then we came up with slightly better abstractions (Perl) and people ran the fuck away from Tcl as fast as they could. Tcl and Unix are based on the same flawed idea: strings are an OK structure. Tcl and Unix were both wrong. Strings suck.
You know what's a good interface? Messages. Look at Smalltalk.
This is what a good OS would look like (good, not great - plus I'll be exaggerating the messages to make my point clearer):
filename.tar.gz expandYourself
or
filename.tar.gz becomeAFreakingFolder
or
filename.mysteryextension expandYourselfWhateverYouAre,IDon'tCareIfIt'sBzipOrGzipOrBlahZip,JustDoIt,YouShouldBeResponsibleForYourself.
and instead of always having to google if ln -s takes the pointer or pointee first, it'd be this:
Unix people are conformists. They don't want change. They want to type tar xgvzg. Let them. Don't waste your breath.
Even Plan 9, the "good unix", is shortsighted. The gimmick is that "everything is a file". Shame, missed it again. Files are dumb. Our friend filename.tar.gz still doesn't know how to manage itself. Files are the wrong abstraction - not enough. How can they never have thought of objects? Because they're conformists. Not too much change, please! Just make more things be files. That'll win Unix people's hearts. And even that failed. Do you see now? Even such a tiny change failed to win over the unix people. You will not convince them that abstracting the behavior they fawn over is a good idea. They don't understand the concept. They're still writing scripts. You know what a script is? A recipe. You know who programs in recipes? Procedural programmers. When you let procedural programmers make an OS you end up with a system where scripts talk to each other via strings. Uhm, gross.
Let it be known that I use a Unix everyday (Mac OS X) and I think it's the best OS we have (I mean Unix, not Mac OS X). Nothing gets close. Still, it's FAR away from good. Smalltalk is good. If Smalltalk were an OS then I'd consider Unix "absolute garbage of the nastiest kind".
Keep abstracting away. If you want, later on when you have nothing to do, go ahead and print the man pages for tar. Read them start to finish. Study them deeply. Even marry them and go on a honeymoon trip together. Then you'll look good to a bunch of internet strangers. Or come with me and appreciate the view from high up our tower of abstractions. Unix people look like ants from here.
After a year working at a Rails shop that deploys to Heroku, I decided it's time to learn some sysadmin basics. Here are some things I've done the past couple months that might give other noobs some ideas.
- Make aliases for most Linux commands. Abstract Linux into a simple interface of aliases that you can browse in your .zshrc/.bashrc/fish.config. Linux becomes much more enjoyable when you can type `untar <file>` instead of remembering the magical incantation `sudo tar -xzvf <file>`. Make aliases for everything. nginx-reload. nginx-restart. alias z="vim ~/.zshrc && source ~/.zshrc". I even abstract apt-get commands into ag-install, ag-update, ag-remote, etc.
- Use dropbox cli, a shared folder with dotfiles, and symlinks to keep dotfiles synced between your server(s) and laptop(s).
- Install tmux on it so that you can `$ tmux attach` to a persistent shell so that things still run when you close your remote connection and they're still there when you log back in.
- Run weechat (terminal irc client) in tmux so that you never have to log out of irc again.
- Learn how to rsync up and down files from your server.
- rsync your Sinatra app (or whatever) onto your server and run it on port 5000, immediately see it live.
- Install nginx and have your VPS serve multiple domain names, each domain name pointing to a Sinatra app running on port 5000, 5001, and 5002.
- Run each website in its own tmux tab. At the beginning it's easier to reason about a foreground process than some daemonized process.
- Install postgres or whatever database you use to your VPS. Get your db-driven app to connect to it. Connect to your remote db using your favorite db gui.
- Take notes of all the commands you use to set up each component so that you can refer to them later, see how you might have messed up.
- Learn enough bash/zsh/fish to automate all of those commands. Polish it enough so that you can curl your script from a Github gist on a fresh VPS and it will set up your entire environment.
- Install `htop` as a nice overview of your server's stats and the processes that are running. Run it in another tmux tab. My tmux right now has a tab for weechat (irc), tabs for my Clojure apps, and an htop tab. On Friday nights I pretend I'm NASA mission control.
- Learn how to use the `ssh` command to reverse tunnel a connection from your VPS to an app you're running on your local machine for a fast development feedback loop.
- Learn how to use your VPS to encrypt your connection when you're working at coffee shops.
I'm still a noob but I leveled up considerably from this quest arc. I highly recommend.
I still don't have a raging clue about most of Linux, even stuff like what all the folders are supposed to be for: /var/opt /etc/www /usr/local /usr/shared/local ... etc. and why files go the places they go, but it's all an iterative process.
Email me (profile) if you need help with any of the bullet points. I am trying to shape it into a more helpful blog post to share with other noobs.