# A beginner's guide to the Unix-style command line

This posts looks into using computer from the command line: how to navigate
around your file system and how to do basic tasks such as; creating/deleting
folders and files, installing packages with apt-get, general terminology,
customizing the terminal, and some more.

![](/images/command-line-tweet.png)

It’s one of the things that seem hard, but actually are not (I mean the basics
aren’t difficult), learn a few commands and tricks, and you’ll find it much
better way of using a computer.

## Terminology

**[Command Line Interface CLI](http://en.wikipedia.org/wiki/Command-line_interface)**
— an umbrella term:

> ... is a means of interacting with a computer program where the user (or
> client) issues commands to the program in the form of successive lines of text
> (command lines).

**[Shell](http://en.wikipedia.org/wiki/Unix_shell)** — the program you’re using:

> The most generic sense of the term shell means any program that users employ
> to type commands.

**[Bash](<http://en.wikipedia.org/wiki/Bash_(Unix_shell)>)** — a type of shell:

> Bash is a Unix shell [...] a free software replacement for the Bourne shell
> [...] it has been distributed widely as the shell for the GNU operating system
> and as a default shell on Linux and Mac OS X.

**[Terminal](<http://en.wikipedia.org/wiki/Terminal_(OS_X)>)** — OS X shell:

> Terminal (Terminal.app) is the terminal emulator included in the OS X
> operating system by Apple Inc..

## Why would I want to learn that?

1. There is a whole cosmos of GUI-less handy applications, you have more stuff
   at your disposal. For me one of the triggers was to be able to use Grunt
2. Linux and OS X use a lot of the same commands, learn one and you know the
   other
3. Servers are mostly Linux, learn to configure it from command line and you can
   run your own server. Configuring a server is the most ideal way to get
   comfortable with shell \*

If you want a more focused introduction to writing reusable command-line
programs, continue with
[the beginner-friendly Bash scripting guide](/basics-of-bash-programming-aka-shell-scripting).

## OS X Terminal

Terminal is in the Utilities folder inside Applications. Here's the default
look.

![Screenshot of the default OS X terminal application](/images/os-x-default-terminal.png)

Very basic OS X terminal as it comes out the box

### Make it prettier and better

I recommend [iTerm](http://www.iterm2.com/#/section/home), it has tabs and bunch
of other cool stuff. Some people also prefer
[TotalTerminal](http://totalterminal.binaryage.com/).

The default look is a bit morose, it can be made more interesting easily. Grab
the `.bash_prompt` file from [here](https://github.com/hilja/dotfiles) and just
drop it into your home directory, boot iTerm. You can customise the iTerm colors
in its Settings → Profiles → Colors (`⌘ + ,`), change the background to your
preference. I like to have my text editor white and terminal black, so I can
distinguish them easily.

![Screenshot of iTerm 2](/images/iterm-setup-on-os-x.png)

iTerm with a custom .bash_profile

## Navigating the filesystem

You go to a directory with the `cd` command.

```shell
$ cd foldername
```

Really important thing is to use tab completion.

![A gif showing tab completion on iTerm terminal](/images/iterm-prompt-tab-completion.gif)

Tab completion

The above gif explained:

```shell
$ cd w<tab>

# Completes into
$ cd web/

# Next dir
$ cd web/be<tab>

# Completes into
$ cd web/beveled-corners
```

Start by typing a few letters of the folder name and then press Tab, and it’ll
fill the whole name in for you. This is priceless!

If there are multiple folders with almost the same name (such as `config.php`
and `config-sample.php`), it won't work right away. Press Tab twice to see all
the files with the same beginning.

## Set of commonly used command

This section is just a **dump of commands basically**.

With these you can get pretty far already. The commands work both in Mac and
Linux (unless otherwise mentioned).

Nomenclatures:

- `$` character means that it’s a line to be written in command prompt (don’t
  actually type the dollar character).
- `#` is a comment.
- If the line starts with nothing, it means it’s an output of a command.

### Navigating

Go to a folder:

```shell
$ cd foldername
```

List files:

```shell
$ ls
```

List also hidden files:

```shell
$ ls -a
```

List as a "list" and show the file sizes in human readable form:

```shell
$ ls -lah
```

Navigate to a different hard drive, usually only needed on a local computer:

```shell
$ cd /Volumes/"Some Volume Name Here"
```

The possible spaces in the directory names can also be escaped with a
backslashes:

```shell
$ cd /Volumes/Some\ Volume\ Name\ Here
```

Where are you (`pwd`: Print Working Directory):

```shell
$ pwd
/path/to/your/current/location
```

### Making

Make a folder (`mkdir`: **M**a**K**e

**Dir**ectory):

```shell
$ mkdir foldername
```

Make a blank new file:

```shell
$ touch some-file.txt
```

Make a file with content:

```shell
$ "your content" > foo.txt
```

Or based onto another file:

```shell
$ cat other-file.txt > foo.txt
```

### Downloading/Uploading

Download a file from internet (`wget`: World Wide Web Get):

```shell
$ wget http://www.example.com/path/to/file.txt
```

Upload file to a server securely (`scp`: Secure Copy):

```shell
$ scp ./my-file.zip bob@127.0.0.0:/var/www/my-site
```

Download file from a server securely (to your current working directory):

```shell
$ scp bob@127.0.0.0:/var/www/my-site/my-file.zip ./
```

Get headers of a website:

```
$ curl -I "https://clubmate.fi"
```

Quickly check if an URL redirects:

```
$ curl -I -s "http://clubmate.fi" | grep Location:
Location: https://clubmate.fi/
```

The `-s` stands for "silent".

### Opening files

Open a file in OS X:

```shell
$ open filename.psd
# Opens to Photoshop
```

Open into a certain app in OS X:

```shell
$ open -a "Adobe Photoshop 7.0" foo.jpg
```

### Moving, renaming, and copying

Move a file:

```shell
$ mv logo.png images/logo.png
```

Rename a file, `mv` is actually a move command, we’re kinda moving the file to
the same directory:

```shell
$ mv index.html index-old.html
```

Copy a file:

```
$ cp index.html index-copy.html
```

Move directory’s content one level up. Basically this:

![Gif showing the dragging of files in OS X finder](/images/move-folder-in-finder.gif)

```shell
$ mv my-folder/* .
```

Even better, you can chain the removal of the now empty directory with the
double ampersand:

```shell
sudo mv my-folder/* . && rmdir my-folder/
```

### Removing files

```bash
$ rm my-file.txt
rm: remove write-protected regular empty file ‘my-file.txt’?
# Answer with y or n
```

Remove a directory:

```shell
$ rmdir my-directory/
```

Remove directory recursively:

```shell
$ rm -r my-directory/
```

Use the force, the "rimraf". Careful with this one, it’s easy to remove too
much, it won’t prompt you and the files can’t be recovered:

```shell
$ rm -rf my-directory/
```

### Viewing and editing

Print out the contents of a file (con**cat**enate):

```shell
$ cat foo.txt
```

Edit a file in your chosen text editor:

```
$ vim foo.txt
$ nano foo.txt
$ vsc foo.txt
```

### Installing packages

Every system comes with its own package manager.

#### Using apt-get, the Debian package manager

Install packages:

```shell
$ sudo apt-get install htop
```

Search for packages:

```shell
$ apt-get search htop
```

Reinstall package:

```shell
$ sudo apt-get install --reinstall package-name
```

Update packages, first update the package list, then the actual packages

```shell
$ apt-get update && apt-get upgrade
```

See this great `apt-get`
[cheat sheet](http://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html).

#### Using Homebrew: the Mac OS package manager

Update the Homebrew package list:

```bash
$ brew update
```

Install a package:

```bash
$ brew install htop
```

Search for packages:

```bash
$ brew search htop
```

Update a packages:

```bash
$ brew upgrade htop
```

Update all packages:

```bash
$ brew upgrade
```

Show all outdated packages:

```bash
$ brew outdated
```

### Quitting processes

Kill a process,
([read more about killing](http://www.cyberciti.biz/faq/stop-process-ubuntu-linux-command/)).
First note the PID, use `htop` for that, then run:

```shell
$ kill -9 <PID-HERE>
```

## Clearing

Clear the terminal window:

```shell
$ clear
```

Or Ctrl+k will destroy the current buffer completely, meaning you
can’t scroll up anymore.

### Permissions and access

Check folder permissions:

```shell
$ ls -l ./my-dir
```

Change owner of a file:

```shell
$ chown my-file.txt
```

Change owner of a directory (recursively):

```shell
$ chown -R newowner my-dir/
```

Change owner and group of a directory and all its files:

```shell
$ chown -R newowner:newgroup my-dir/
```

Change group only:

```shell
$ chown -R :newgroup my-dir/
```

Add user to a group:

```shell
$ sudo usermod -a -G www-data username
```

Add your user to a group, to www-data in this case:

```shell
$ sudo usermod -a -G www-data username
```

Change permissions recursively, but to directories only. This change all
directories in the current working directory to `755`:

```shell
$ sudo find . -type d -print0 | xargs -0 chmod 0755
```

This one changes all files to `644` recursively, but doesn’t touch directories:

```shell
$ sudo find . -type f -print0 | xargs -0 chmod 0644
```

### User switching

Switch users. This comes in handy in a server environment (`su`: Switch User):

```shell
$ su username
```

Or switch to root with sudo:

```shell
$ sudo -i
```

Switch back to your original user:

```shell
$ exit
```

## User management

Make a new user:

```
$ sudo useradd bob
```

Change currently logged in users password:

```shell
$ sudo passwd
```

Change other user password:

```shell
$ sudo passwd bob
```

### Restarting, booting, and exiting

Reboot a machine, rarely needed but not never:

```shell
$ sudo reboot now
# Or only a reboot worked just as well
reboot
```

Turn the machine off:

```
$ shutdown
```

Or halt:

```
$ shutdown -H
```

Exit the machine or a user you’re in:

```bash
$ exit
```

### Finding stuff

Look from the current working directory `.` a file named `foo-bar.svg`:

```
$ find . -name foo-bar.svg
```

Locate your `php.ini` file:

```shell
$ php --ini
```

### Misc commands

Get the system time in Ubuntu (clock):

```shell
$ hwclock --show
```

Get status of a service in Ubuntu, mysql in this case:

```shell
$ service mysql status
```

Get all installed packages in Ubuntu:

```shell
$ dpkg --get-selections | grep -v deinstall
```

Reload NGINX:

```shell
$ sudo nginx -s reload
```

Restart any service after changing setting, NGINX in this case:

```shell
$ sudo service nginx restart
```
