Hacker News new | past | comments | ask | show | jobs | submit login
The Command Line Crash Course (learncodethehardway.org)
126 points by unmole on Jan 10, 2014 | hide | past | favorite | 54 comments



Well, pleasant surprise people are finding this book. Heads up, it'll be getting a little update soon so that it matches the version that is now an appendix in Learn Python The Hard Way. I stripped out a few commands that weren't as useful and also added some more help on what to do when you get stuck (what I call the "reset"). Check out http://learnpythonthehardway.org/book/appendixa.html for the newer streamlined content.

In general I found these 14 commands end up being the smallest number anyone really needs to do basic CLI work, but keep in mind that the goal of the book is to give someone just enough experience to be able to go through my other books. There are plenty of more in-depth books on managing a server, so I don't bother to duplicate their work.

If you really want to learn how to manage servers and work the CLI, then check out "UNIX and Linux System Administration Handbook (4th Edition)" by Evi Nemeth and friends. My recommendation to people is to get a crappy computer you don't want, put OpenBSD on it following their http://www.openbsd.org/faq/faq4.html guide exactly, use the Nemeth book to configure every service you can and then point a security scanner at your box (like Nessus, or whatever they use today).

Once you can setup an OpenBSD box, get services running on them, and secure those services based on known attacks, then you can pretty much do anything. More importantly, OpenBSD is very bare bones so you learn the core of how a Unix system works and how to configure it, but their docs are very thorough and complete so you can do it if you follow them accurately.

Hope that all helps.


> In general I found these 14 commands end up being the smallest number anyone really needs to do basic CLI work..

What should an advanced user know? Everything provided by coreutils, stuff that goes in /bin etc? Also sed, awk and common tools for simple text processing?


After these commands I don't think learning a ton of more commands makes you better at working a computer. After this, sitting down to actually setup a working Unix box and then hardening it will teach you a crazy number of commands and things. More importantly it'll teach what all those little processes and services do on the computer.

However, I will say that learning how to effectively use grep and sed are probably the only big omissions from my list. But, those are outside the scope of this little book given those commands have whole books devoted to them.


Well said! Its probably the tinkering that eventually teach people that something that is in coreutils is worth looking into.


I think there are several valid definitions for "advanced" in this context. While basic awk/sed knowledge is certainly useful -- if you can do the same thing in python/ruby/perl that might be fine.

Knowing a little bit about writing valid ksh/bash shell scripts (being at least aware of bash-isms) would certainly be useful for sys adm work.

My opinion is that the full gnu (and/or bsd) userland has grown so large over the years, that saying that you should know it all is probably overkill -- but knowing how to look things up (man, info) is a must.

As Zed's implied -- GNU documentation could stand to be improved vs bsd man pages -- although the info manuals can be quite useful.


I can't recommend "UNIX and Linux System Administrator Handbook" enough it has definitely helped my burgeoning career as a sysadmin. Also I've learned tremendously from zed's C, Ruby, and Python. Thanks Zed for putting all of that together. Lastly RIP Evi Nemeth, so many Sysadmins are greatly indebted to your gifts.


Do you think the same benefit could be had from doing it on EC2, or is installing OpenBSD locally from a CD-ROM essential to your suggestion?


Although not as deep as Zed's books/tutoriuals. I have created several screencasts about the topic. Basically, I show you what a UNIX-like filesystem looks like, some common commands, and then show you man pages by example. This should be enough to get someone going and teach them how to learn for themselves.

Crash Course on Common Commands @ http://sysadmincasts.com/episodes/13-crash-course-on-common-...

Crash Course on the Filesystem Hierarchy Standard @ http://sysadmincasts.com/episodes/12-crash-course-on-the-fil...

Crash Course on Man Pages @ http://sysadmincasts.com/episodes/19-crash-course-on-man-pag...

ps. there are many great HN threads about UNIX commands, here are just a few:

https://news.ycombinator.com/item?id=6360320

https://news.ycombinator.com/item?id=6046682

https://news.ycombinator.com/item?id=5022457

https://news.ycombinator.com/item?id=4985393


The "Unix Programming Environment" book by Kernighan and Pike is still the best source for a UNIX command line "course". I love the elegance of this book, I learned most of what is in it already by "osmosis" before buying it, still love to skim it just for how masterly it is written and how nicely the problems are approached, definitely something to aspire to.


Speaking of "The Unix Programming Environment":

I was reminded, by this comment:

https://news.ycombinator.com/item?id=7036920

by danso in this thread (who talked about cp and mv), that I learned, from the K&P book (IIRC), that the commands cp, mv and ln were actually all links to the same executable, which did the right thing based on what name it was invoked by, as found from looking at argv[0]. Checked just now in Linux with:

cd /usr/bin ls -li cp mv ln

on SuSE Linux, but they seem to be different files now ...

The -i option to ls shows the inode number.


Well, if you "want" that, you could also have a look at busybox -- which does cp,ls,mv and more -- in a single binary (optionally statically linked).

I actually tend to do a switch on the first argument for certain shell scripts, such as this little thing for switching between single display on a couple of laptops/netbooks:

    #!/usr/bin/env sh
    INTERNAL=LVDS
    EXTERNAL=VGA-0

    for monitor in `xrandr|grep connected|awk '{ print $1 }'`
    do
      case "${monitor}" in
        "LVDS")
          INTERNAL="LVDS"
          ;;
        "DFP1")
          EXTERNAL="DFP1"
          ;;
        "CRT1")
          EXTERNAL="CRT1"
          ;;
        "VGA-0")
          EXTERNAL="VGA-0"
          ;;
      esac
    done

    twoscreen()
    { 
      xrandr --output ${EXTERNAL} --auto --rotate normal --pos 0x0 \
             --output ${INTERNAL} --auto --rotate normal --pos 768x1152
    }

    vgaonly()
    { 
      xrandr --output ${EXTERNAL} --auto --rotate normal --pos 0x0 \
             --output ${INTERNAL} --off
    }

    laptoponly()
    { 
      xrandr --output ${INTERNAL} --auto --rotate normal --pos 0x0 --output ${EXTERNAL} --off
    }

    fn=`basename "$0"`

    case $fn in
      "twoscreens")
        twoscreen
      ;;
      "onescreen")
        laptoponly
      ;;
      "vgaonly")
        vgaonly
      ;;
      *)
        echo "Usage: vgaonly|onescreen|twoscreen"
        echo "called as: $0 ($fn)"
      ;;
    esac
         
As a side note, for those running Debian (or Ubunut, I think) there's a couple of utilities to help search for binaries/files -- namely apt-file and dlocate. Eg:

    apt-file search -F bin/cp #returns coreutils
    # -F does a fixed string search, otherwise you'll
    # get a list of all packages which contains files
    # that *contain* bin/cp in their name such as:
    #   passwd: /usr/sbin/cpgr
Dlocate works with regular expressions and an index, so it's much faster and you can do:

    $ dlocate bin/cp\$
    coreutils: /bin/cp


>if you "want" that, you could also have a look at busybox

Don't want or need it, just mentioned it as an interesting bit of Unix history. I guess the 3 files are not links but separate files nowadays due to much cheaper and more plentiful disk space compared to those days.

Your script is interesting.

Didn't know about apt-file or dlocate, good to know, thanks.

>Ubunut

Sort of Freudian slip? Just kidding :)


+N. I never tire of recommending K&P to wannabe Unixers. I've said to participants of Unix courses I conducted using the book, that it (and K&R - the C book) are like Sanskrit shlokas - both are concise, and sometimes have multiple layers of meaning, which one might not get all of, on a first reading.



Another great resource is "The Linux Command Line: A Complete Introduction." I picked up a lot of command-line fu from this book.

http://www.amazon.com/The-Linux-Command-Line-Introduction/dp...


The Linux Command Line is definitely a good book. It's actually available for free here if anyone is interested: http://linuxcommand.org/tlcl.php


Yes, that one is good. I reviewed it here for O'Reilly:

http://shop.oreilly.com/product/9781593273897.do#PowerReview

Mine is the 2nd review from the top, currently; the one titled "A useful book for beginners to Linux".


Understanding the shell, both memorizing its syntax and appreciating how it and the GUI are an abstraction of something deeper (though I find it helpful to think of the GUI as the abstraction for he command line), is under appreciated when it comes to learning to code, so a guide like this is really helpful to point to.

What do people think of the shortness of the chapters? That is, having hem cover one command each? I would lean toward combining similar concepts, such as cp and mv, so that the higher-level capabilities, the ones that make the shell uniquely more powerful than the GUI (such as piping), stand out more...but maybe it's better to have things one at a time?


The GUI is not an abstraction for the command line, it is a totally unrelated implementation, with literally no layered code. They are both interfaces to the kernel API, but the way they are built is very different.


I find it interesting that very few people know about the "cd -" command (goto previous directory). I find it invaluable, but never see anyone else use it (this tutorial included).


"cd -" and also using "cd" with no arguments to get back to $HOME are great tips. I also have a bash function called "up" to get back N directories up the hierarchy so I can do "up 5" which is like "cd ../../../../.." but much easier to type.

    up () {
        if [[ $# -eq 1 && "$1" -gt 0 ]] ; then
            local i d
            for (( i = 0; i < $1; i++ )) ; do d="../$d" ; done
            cd $d
        else
            echo "Usage: up N"
        fi
    }


I'm on my phone at the moment, but I did something similar except avoided the counting. I have a shell function called `ct` for "climb tree" where you specify the name of the directory you want to climb to; calling it will place you in the first directory above cwd whose name matches the argument and in addition I wrote a bash completion module for it so I only have to type minimal characters. I'll post the source for both shortly.


Here's the script for ct:

http://pastebin.com/M1k1WL88

Looks like I wrote the tab-completion script on my work machine. I don't have access to it right now, but if I remember when I do have access I'll pastebin that as well.


This is awesome! You are awesome! :-)


Here's the tab completion script:

http://pastebin.com/mR8y1Rks

Note it's the only tab completion script I've written, and it's probably a hack :P


Thanks for following up. I think I'm going to play with this later this week.


No worries. Just throw them both in your .bashrc and you should be good to go.


I like this concept. My solution has been to use '..' '...' and '....' to go up 1,2,and 3 directories.


oh-my-zsh does this out of the box.


Your function called "up" reminds me of long-ago-used Novell Netware version, in which, IIRC, you could do:

cd .. # to go one level up

cd ... # to go two levels up (note: 3 dots, not 4, makes sense when you think of "cd ." and "cd ..")

# and so on.


I didn't know this one, and glad I do now! Is it possible that the other one I wish existed is already commonplace? I'd like to have an arg that cd's to a directory automatically after mkdir'ing it... or mv'ing a file to a directory.

Something like:

mkdir foo -go and mv foo ~/bar -go

... Probably simple enough to script, but I guess I'm too lazy at the moment.


You could have scripted it faster than doing that comment ...

Or, you could just

    bash$ mkdir -p /some/dir/to/make
    bash$ cd !$
Bang (!) is a history lookup with lots of variation in use. It probably works in other *nix shells too.

Look under "event designators" in "man bash" for more info.


I typically use:

    $ mkdir foo
    $ cd !$
Not quite what you're asking for but it can certainly save some keystrokes -- especially if you're doing something like:

    $ mkdir -p foo/bar/baz/whatever


I use the version at http://onethingwell.org/post/586977440/mkcd-improved, called `mkcd`.

  # mkdir, cd into it
  mkcd () {
      mkdir -p "$*"
      cd "$*"
  }
Just copy and paste that at the end of your `.bashrc` or `.zshrc` file. You may also want to include this comment above it so you know why it’s written like that:

  # from http://onethingwell.org/post/586977440/mkcd-improved


$_ in bash means the last argument of the previous command. So:

mkdir some/long/path/to/a/dir cd $_

mv foo some/long/path/bar cd $_

both work for what you want, and the extra keystrokes are so few that it hardly matters. The $_ is not specific to those two commands, so works for others as well, and is typically very useful because command sequences often tend to need the last argument of the previous command in the next command; un-tar-ing a .tar file and then going to the extracted directory is another example.


function take_dir { mkdir -p "$1"; cd "$1" ; }; alias take="take_dir"


I call my version of this function 'enter'.


I use it a lot. I wish i could add multiples to go backfurther....

i.e.:

cd /var/log

cd /etc/ssh

cd /home/samstave/Downloads

cd -- (takes me back to /var/log/)


    pushd /var/log
    pushd  /etc/ssh
    pushd /home/samstave/Downloads

    popd;
    !! (takes me back to /var/log/)
You could alias cd to pushd and cd- to popd...


I use pushd/popd/dirs for multiples. I have aliases like p1 for "pushd +1" and so on.


cf. pushd and popd


That's weird. "cd" with options was one of the first commands I learned.


you just made my day :)


Idea: Create Anki decks to go along with the material. Anki is flashcard software with spaced-repetition learning.


Big fan of https://sivers.org/srs - would have never started using spaced repetition without it.


I don't know -- if you learn this stuff, it is presumably to use it -- so you'll get repetition from actually doing the stuff? This is quite useless knowledge if you're not going to be using the command line IMNHO (I do use the command line all the time -- I don't see why someone should learn to do that if they're not going to use it though...).


Please finish the other books as well!


Command line crash course? I can crash your command-line real easy. :(){ ;|;& };:


[deleted]


Because some people just need to get around in a shell, not obtain an unofficial doctoral on it.

Here, let me quote from the first couple paragraphs of the first page of the book:

  I wrote this book really quickly as a way to bootstrap students for my other 
  books. Many students don't know how to use the basics of the command line 
  interface, and it was getting in the way of their learning.

  This book is designed to be something they can complete in about a day to a 
  week and then get enough skill at the command line to graduate to other books.

  This book isn't a book about master wizardry system administration. It's just 
  a quick introduction to get newbies going.
That said, I always like to see a brief introduction to commands like cut and awk, as they are tremendously helpful for pulling stuff out of text data files and they kind of show off the (simple) power of shell. But I've read the first paragraph of the first page of the book and know that wasn't Zed's goal here.


You're being pedantic and obtuse. In your world people should get an Automotive Engineering degree before driving.

Zed teaches enough CLI to allow students to accomplish the basics so they can learn Python or C. Ideally they will expand on the material and also complete the bonus assignments in the material.

And man pages suck for absolute beginners. There's too much information overload and a beginner hasn't the context to know what is useful for his immediate needs.


Is it me, or does the HTML version not have any "Next/Prev" pagination buttons?


Yup. I'm reading Learn Python The Hard Way and it's the same.

I'm actually glad it's set up that way. I assume the paid version is more streamlined. I can't get too upset that I have to hit an extra button to access free content.


The problem I had when I wanted to read a somewhat in-depth tutorial on Linux / the Linux terminal (one or both), is that the tutorial said that it assumed that you were a sysadmin. What? I couldn't just be a regular user who has none of the experience and few of the needs of a sysadmin? No wonder Linux has a reputation for being needlessly impenetrable.

(I don't recall the exact tutorial or if it is representable of such tutorials in general.)


I heartily second Stiff's recommendation for Kernighan and Pike. (And being from the 80s, it assumes more of a multi-user Unix environment as apposed to a sysadmin p.o.v.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: