Instead of using a simple lifetime average, Udemy calculates a course's star rating by considering a number of different factors such as the number of ratings, the age of ratings, and the likelihood of fraudulent ratings.

Learning the UNIX Command Line on OS X

Mac beginners can easily become power OS X users by using the Terminal to interact with the UNIX shell.

4.2
(91 ratings)

Instead of using a simple lifetime average, Udemy calculates a course's star rating by considering a number of different factors such as the number of ratings, the age of ratings, and the likelihood of fraudulent ratings.

Several decades since its inception, UNIX is still at the heart of the Internet and computing in general. In my view, a tool this powerful that has withstood such a rapid change in a fast-paced industry is something that needs to be learned and used regularly.

If you own a Mac and are a programmer, software engineer, web developer or designer, network or systems engineer, or simply interested in learning more about your system, you're really missing out if you don't learn the UNIX command line. It is simply one of the most powerful technical skills you can have available in your arsenal.

At the end of this course, students should possess the skills necessary to start using the UNIX operating system with greater proficiency, as well as the ability to learn more about the system on their own.

Who is the target audience?

Beginner & intermediate level users who are new to the UNIX operating system will benefit the most

The goal of this course is to provide an introduction to basic UNIX commands and concepts. At the end, students should possess the skills necessary to around the operating system, as well as the ability to learn more about the system on their own.

Why should I learn the UNIX command line?

Before embarking on this course, you might be asking yourself, "Why should I learn the UNIX command line?". In this chapter I'll discuss a brief history and background of UNIX and it's overriding philosophy, as well as why I think it's so important to anyone interested in software development or systems administration.

Getting started using the Terminal

In this section, we'll need to select software that gives us the ability to type in shell commands. Before we even get into the various concepts and commands that UNIX offers us, we need an application that gives us a command line, which is essentially an interface to a shell.

This kind of software is often referred to as a terminal emulation program, or more commonly, a terminal. We'll cover how to easily access the default Terminal application provided by OS X through using The Finder, keyboard shortcuts, desktop shortcuts and Spotlight, as well as how to select and import new Terminal profiles (or themes. Finally, we'll also see how to configure it's various settings to adjust the look and feel.

This quiz will cover some of the basics of easily accessing the terminal.

Getting started using the Terminal

7 questions

+–

Getting Help

1 Lecture
12:49

Getting Help

In this chapter, we'll be covering various ways of getting help on a UNIX system, such as using the man command to access the available system manual, as well as how to decipher the man page style, syntax and structure:

We'll take a closer look at commands such as apropos and whatis, which help you find new or related commands to the command you're looking up.:

apropos keyword ...

whatis keyword ...

Finally, we'll cover the lesser known commands such as help and info:

info [OPTION]... [MENU-ITEM...]

help [-s] [pattern ...]

Getting Help

12:49

In this quiz, we'll cover the basics of accessing the system help facilities available in UNIX.

Getting Help

10 questions

+–

Managing files and directories

10 Lectures
39:08

Directory hierarchy

Being able to work with files and directories is essential to using the UNIX operating system. We'll start off with a basic overview before diving into specific commands for manipulating the file system.

In UNIX, as in many other operating systems, a file system is a collection of directories and files that are organized in a tree-like structure. The files contained within that tree can be one of many different types, including regular files, directories, block or character devices, sockets, symbolic links and named pipes. We'll introduce the touch command, which provides the ability to create blank files quickly, which will help us jump into more complex commands later quickly.

Wildcard basics

In UNIX you have the ability to specify patterns to make using commands such as ls and grep more powerful. These patterns are normally referred to as "Wildcards". We'll cover the most common Wildcards such as the "star" (e.g., an asterisk character *), the question mark ?, and square brackets [], here in this video.

Wildcard basics

04:09

Directory Basics

We've already seen that we have directories already on our system, but what if we want to create a directory on our own? In this video we'll discuss how to do that with the mkdir command, as well as how to navigate directories using cd, the "change working directory" command.

mkdir [-pv] [-m mode] directory_name ...

cd [-L|-P] [dir]

We'll also cover the "print working directory" command pwd, the tilde character's ~ usage, as well as special directories such as . and .. - and what they represent.

pwd [-L | -P]

Directory basics

04:18

Viewing Files

Let's now see how we can view files. By doing this, we'll be able to inspect the contents of the files and have a better grasp of what happens when we move files, copy them, or manipulate them in other ways. Here we'll look at a number of commands that enable you to view files, such as cat, less, more, head and tail.

Moving Files

Sometimes instead of copying files around, you simply want to move them. In UNIX, the cp command is similar to mv in that you type the command, followed by a source file, and then finally a destination file or directory.

mv [-f | -i | -n] [-v] source target

Moving Files

02:33

Removing Files

Now that we've learned how to create files and manipulate them in a variety of ways, sometimes it's useful to do a little housekeeping and clean up our mess. Here we'll see how to do that with the rm command, which can be used to remove files and directories:

rm [-dfiPRrvW] file ...

rmdir [-p] directory ...

Removing Files

04:00

Searching Files

Sometimes it's helpful to have the ability to search through files. Maybe you've been working on some markup in HTML or CSS for a website or writing some code in a language such as Ruby or Javascript, and you need to search for a pattern, such as CSS class name, a function or method name, or some string that you need to change. You might have many files that contain this string of characters, so manually opening these files would be too cumbersome and time-consuming to do in an effective way.

In those situations, one command that would be helpful is the command:

Finding files

Before we wrap up this chapter, I'd like to touch on a very important command that becomes much more useful as your system grows. Over time you can accumulate more files and need to be able to quickly find them or perform some general housekeeping, such as delete files that are simply too large or unnecessary, or possibly change permissions for a batch of files.

One of the best ways on UNIX to locate files is to use a command called find.

Understanding directory and file permissions

To fully understand how to manipulate files and directories, it is important to remember that a file system can provide various levels of access to users through a permissions-based system. In this chapter, we'll cover the basics of how to read and change permissions so that you can have a better understanding of the file system, as well as how to manage who has access to files and directories within it.

Introduction to the chmod command with symbolic notation

In this section we cover the various permissions classes, as well as symbols for specifying those classes, their corresponding operators and the permissions themselves. This is done to show how to manipulate file and directory permissions through the chmod command:

Various examples of permission settings are shown using symbolic notation. Here are a few samples:

chmod u+w,g-w,o-w file
chmod ugo= file
chmod a= file

Introduction to the chmod command with symbolic notation

09:32

The X flag

If a file is already executable, adding the X flag to the permissions makes it executable by all permission classes. In this video we discuss the various effects of the X flag on files and directories.

chmod g=x file
chmod u=rw,+X file

The X flag

03:00

Setuid

The setuid concept, which is a shorthand way of saying, "set user id upon execution", is a flag used to determine what user a file will be run as upon execution. This idea will make more sense when we cover UNIX processes later on, so for now let's just focus on how we can identify this setting and change it to suit our needs.

chmod u+s file

setuid

01:50

Setgid

The setgid concept, which is a shorthand way of saying, "set group id upon execution", is a flag used to determine what group a file will be run as upon execution.

chmod g+s file

setgid

01:41

The sticky bit

The sticky bit is a technique that is commonly used on shared directories, or directories containing temporary files, such as the /private/tmp directory on the Mac, indicated by the t in the far right position of the permission flags:

Some permissions have special attributes, as indicated by the @ symbol, while others have ACL settings, as indicated by the +. Notice how the ~/Library directory below has special attributes associated with it, while all other directories have ACL settings:

Numeric notation introduction

Now that we've covered the basics of the chmod command using symbolic notation, it's time to look at an alternative format for manipulating file and directory permissions. That alternative is called Numeric notation and it provides the ability to change permissions in a much less verbose manner than symbolic notation.

So let's revisit an example of symbolic notation:

chmod u=rwx,go=rx file

This explicitly says that the User class should be set to read, write and execute permissions, and the Group and Other class should be set to only read and execute permissions.

Using numeric notation, this can be done just as easily like this:

chmod 755 file

So how does u=rwx,go=rx get converted to 755?

Numeric notation introduction

07:15

Numeric Notation - Special Flags

We've already covered the basics of setting permissions, but there still are a few special flags that need to be addressed. Those are setuid, setgid and the sticky bit, which were covered previously in the section on symbolic notation. These flags will occupy another bit position, to the left of the normal permission flags:

User Group Other
Special User Group Other

So as an example, if we had read and execute permissions set for all permission classes, and write permission set for only the User class, we'd have something like this:

chmod 755 file

If we wanted to set a special flag, we would place another number to the left of the permissions:

chmod 4755 file

Numeric Notation - Special Flags

05:58

+–

Redirection and Pipes

12 Lectures
31:14

Redirection and Pipes

One of the most important features of a UNIX operating system is it's ability to manage streams of data and redirect it to an appropriate destination.

Having the ability to take the output of one command and feed it as the input to another command is one of the hallmarks of UNIX. It's part of what makes the operating system so remarkably powerful, and allows programmers and systems administrators alike to build more complex applications by chaining together many smaller, more focused utilities. It's one of the main reasons that they are able to "write programs that do one thing and do it well", as we discussed in a previous chapter.

In this section we'll uncover the various ways that you can use this feature of UNIX to capture, redirect and filter data.

UNIX streams

The way UNIX manages streams of data is by using file descriptors, which are essentially integers that identify open files. Every UNIX operating system has access to at least 3 common file descriptors: standard input, standard output and standard error.

Here's an overview of those files descriptors and their locations on the system:

Standard input is data that is read into a program. A common example of standard input is reading data that a user types from a keyboard. Of course, standard input can also be accepted from commands and utilities, as we'll seen in a moment.

Standard output is data that is written from a program. For example, when a command writes data to the screen or terminal, that is considered to be standard output. Of course, that data doesn't have to be written to the screen, as it can also be redirected to other programs.

Standard error is basically the errors that a program outputs, such as if you pass the wrong arguments to a command, it will issue a warning or error that is written to standard error, which in many case is the screen or terminal.

To fully grasp these concepts, let's look at the various ways that we can use these standard data streams.

UNIX streams

02:27

Redirect standard output from a command to a file

Let's now send the standard output of one command to a file. Reviewing the fruits file, we can see we still have some data to work with:

iMac:~ screencast$ cat fruits
apple
orange
banana

I'm going to revisit a command that we've used previously for displaying some data from this file. That command is head, which normally displays the first 10 lines of a file, but you can also pass the n option to specify how many lines you'd like to show. In this case, I just want the first line of the file to be shown:

iMac:~ screencast$ head -n1 fruits
apple

As you can see, it wrote the line containing apple to the screen. Now let's redirect that output to a file using our redirection operator:

iMac:~ screencast$ head -n1 fruits > fruits-2

Notice how this time nothing was written to the screen? That's because the standard output was redirected to the fruits-2 file, instead of the screen which is its default location.

Let's review that newly created file:

iMac:~ screencast$ cat fruits-2
apple

As you can see, the output from head was indeed written there.

Redirect Standard Output with >

05:12

Redirect stdout with append operator: >>

Let's say that you don't want to overwrite a file, but instead simply want to append the standard output to the end of a file. In that case, you can just use the append redirection operator, which is represented using 2 greater than symbols >>. Let's look at an example to see this in practice. First, we'll display the contents of the fruits file:

iMac:~ screencast$ cat fruits
apple
orange
banana

Then we'll follow an example similar to what we tried before with the cat command, but this time we'll use the append redirection operator. I'll type in some data, then just like before I'll type Ctrl-d when I'm done:

Let's say I want to sort this file, but I also want to save the contents to a separate file altogether. This can easily be done using both redirection operators

Redirect STDIN then STDOUT

01:21

Redirect stdout and stderr

As we've discussed earlier, standard output and standard error by default are separate locations. Let's use an example to help clarify this concept. I'm going to get a file listing of 2 files, except that one of them doesn't exist:

Here we see an error for the non-existent vegetables file, as well as file details for existing the fruits file. This seems normal, but there's something going on behind the scenes that might not be immediately apparent.

Redirect STDOUT and STDERR

04:01

Redirecting stdout and stderr to separate locations

Sometimes it would be nice to redirect both standard output and standard error, but we'd prefer to have the results sent to separate locations. First I'll clean up our old output files:

iMac:~ screencast$ rm errors.txt output.txt

Then we can try an example:

iMac:~ screencast$ ls -l fruits vegetables > output.txt 2> errors.txt

Redirect STDOUT and STDERR to separate locations

01:18

Redirect stdout to nowhere

Let's say I have a program that generates an error and I'm not interested in seeing it. I can send that error to a place commonly referred to as a bitbucket, which is /dev/null.

Redirect STDERR to nowhere

01:31

Example of a "here" document

Let's say you want to test out a command using some sample text, but want to do so without opening a text editor. Basically what you need is a temporary document. In UNIX-speak this is more commonly referred to as a "here" document.

Let's create one with the cat command to demonstrate the idea.

iMac:~ screencast$ cat <

Example of a "here" document

01:46

Pipes

In this section we'll cover how to use UNIX pipes, which in my opinion is one of the most important and powerful facets of the operating system.

The concept of pipes is quite simple:

"The output of one command is sent as the input to another command"

That use of pipes is represented by the vertical bar character |.

Let's revisit our "here" document example from the previous section.

Pipes introduction

02:37

Example from "Top 10 UNIX commands"

In this example, I'll show a more practical use of pipes that has been very useful in my own workflow. I need to credit Ben Orenstein @r00k for the original idea. Since I first heard of it, I've posted this tip on my free UNIX newsletter at http://unix.chipcastle.com and received a really positive response. Based on that feedback, I've come up with a variation of this tip, which I'll show here.

So what I'd like to do is find out the Top 10 UNIX commands that I currently use. Having this information is valuable because I can then create short aliases for these commands, thus I can speed up my workflow because I'll type much fewer keystrokes. It might not sound like a big improvement at first, but if you type certain commands dozens or hundreds of times a day, the time savings can really add up over the long term, not to mention the reduced wear and tear on your fingers.

Top 10 UNIX commands

04:36

The tee command

To wrap up this chapter, I wanted to show you a technique that combines the idea of output redirection with the functionality of UNIX pipes.

The tee command

02:18

+–

Working with Processes

7 Lectures
23:54

UNIX processes

To start of this section, let's first think about the definition of a process.

A process is an instance of a computer program that is being executed

Examples of this include any time you run a shell command such as ls , cd, or many other built-in commands, or when you launch an application from the OS X Finder.

Viewing running processes

To see evidence of this, we have a couple of commands that are especially helpful in viewing running processes.

Run a command in the foreground

Most of the commands and utilities we've worked with so far in this tutorial have been run as foreground processes. This isn't easy to verify because most of the commands run so quickly, the processes are spawned and die almost instantly, as when we run commands such as cd, ls and many others. However, the idea of foreground processes becomes more apparent and important when we have a long-running process.

Foreground processes introduction

02:43

The jobs command

For us to better grasp the concept of foreground and background processes, we need a way to inspect and manage them. The jobs command is an excellent way to do that, so let's look use the help utility for this builtin shell command.

iMac:~ screencast$ help jobs
jobs: jobs [-lnprs] [jobspec ...] or jobs -x command [args]
Lists the active jobs.
The -l option lists process id's in addition to the normal information; the -p option lists process id's only. If -n is given, only processes that have changed status since the last notification are printed. JOBSPEC restricts output to that job. The -r and -s options restrict output to running and stopped jobs only respectively. Without options, the status of all active jobs is printed. If -x is given, COMMAND is run after all job specifications that appear in ARGS have been replaced with the process ID of that job's process group leader.

The jobs command

01:15

Run a command in the background with &

Let's start over by running the find command, except this time let's redirect standard output (stdout) and standard error (stderr) to a file named plist.out.

We're also going to run this command in the background, which can be done by appending our command with an ampersand symbol &:

Running a command as a background process allows us to continue with our work. So let's do that by inspecting the processes that we're currently running.

Background jobs introduction

02:57

Bring a background process to the foreground: fg

To complement the ability to send processes to the background, we also have the ability to bring processes to the foreground, using the fg shell builtin. Let's view the help documentation for this command to get more details:

iMac:~ screencast$ help fg
fg: fg [job_spec]
Place JOB_SPEC in the foreground, and make it the current job. If
JOB_SPEC is not present, the shell's notion of the current job is
used.

So let's take a look at an example of this command.

The fg command

03:07

Killing processes

Having all of these processes is great, but sometimes you need a way to destroy a process. Maybe you typed the wrong command, or there's a process that is eating a huge amount of memory or consuming too many cpu cycles. Regardless of the scenario, you need to prevent the process from continuing. This can be done using the kill command.

The kill command is really just a facility for sending a signal to a process. Using the -l option, we can view a list of all signals that can be sent:

To send a signal to a process, we'll use the kill command, followed by an optional signal and finally the process id, orpid, that we'd like to communicate with. By default, the TERM signal is sent to the process id if one isn't specified.

Killing processes

05:05

+–

Installing software from the command line

6 Lectures
24:34

Using curl

Now that we have the traditional software installation methods out of the way, it's time to get back to the command line. Let's follow an example of installing software from there, except this time we're going to use a common OS X application called curl. The curl utility essentially allows you to transfer a file from a specified url on the Internet to your local machine.

What I'd like to do is download a great application from 37signals called Pow, which is a Rack-based web server for the Mac. According to the installation instructions, we'll use curl to fetch a file and then pipe the downloaded data to the shell, which will then run the file as if it were a shell script already on our file system.

Before blindly doing something like that, I would advise you to visit the site first with your web browser or simply download the file with curl to inspect its contents.

Let's use our browser to do that, and I'll go to the site to inspect the shell script's source code (http://get.pow.cx). Since I've run this script many times and know it comes from a trusted source, I'm comfortable with running the installation command provided on the site:

iMac:~ screencast$ curl get.pow.cx | sh

The curl command

01:45

Package management with Brew

Since I've started using Brew I've run into fewer problems with software package management on my Mac. For most packages, I've found that it "just works", so I've been quite happy with it.

Before I cover the basics of using Brew, I would like to encourage anyone following this tutorial to refer to the website for the most up to date documentation on how to use it effectively, as the commands that follow could potentially change in the future. Alternatively, you can use the help provided by Brew or refer to it's man page:

brew help
man brew

At the time of this writing, the installation of Brew requires the following command:

ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

Since I already have it installed on my machine, I'll be skipping this step, but please feel free to pause for a moment and install it on your local machine if you want to follow along.

Package management with Brew

06:30

zip

To create files with a .zip extension, we need to use the zip utility, which is capable of packaging and compressing files.

unzip

In contrast to zip, we have the unzip utility, which gives us the ability to list, test and extract compressed files in a ZIP archive format.

The zip and unzip commands

02:12

The gzip command

An alternative to using unzip is another archive extraction utility called gzip, which compresses files into an encoding scheme using the Lempel-Ziv algorithm.

The gunzip command

An alternative to using unzip is another archive extraction utility called gunzip, which expands files that were encoded using the Lempel-Ziv algorithm.

The tar command

The tar utility has been around for several decades and was originally used to write data to devices for tape backup purposes, but today it is still used for packaging files into one larger file for distribution or archiving.

The gzip, gunzip and tar commands

08:15

Using compress and uncompress

Moving on to our last compressed file format, you'll occasionally see files with a .Z suffix. This type of file is created using adaptive Lempel-Ziv coding. This file format isn't as common as the others previously shown, but I'd like to show you the basics to help you get started.

The compress & uncompress commands

01:31

Installing from source

To wrap up this chapter, we're going to briefly cover installing software from source code.

Using the download from earlier for the Tcl language, I'm going to change into that directory so we can perform the installation:

$ cd ~/Downloads/tcl8.6.0

Usually you'll find a README or INSTALL file in most common UNIX packages, so I encourage you to always read those files first, as they have a lot of details that might be important depending on the type or version of system you have installed.

For this package, it refers me to the online installation instructions, so let's go there and check them out. From there it tells me to change into the unix directory before proceeding with the installation, as there are a number of target platforms supported for the Tcl language.

The basic approach for installation Tcl from source is the following:

$ ./configure
$ make
$ make test
$ make install

This process is not unique to the Tcl language. In fact, it's generally the same steps for any UNIX package which you'll install from source.

So, let's break down each step.

Installing software from source

04:21

+–

Features of a UNIX shell

2 Lectures
11:30

Features of a UNIX shell

To get the most out of your system, you'll need to have a reasonable understanding of the UNIX shell. To that end, it's important to understand that each shell has specific capabilities built-in including commands such as cd, pwd, kill and many others, as well as certain features that are specific to your current login session, which are commonly referred to as your "environment".

Environment variables

Within an "environment" a user has access to a number of variables that helps them determine the current state of the session, as well as the ability to manipulate that environment.

To have a clearer understanding of what an environment is, let's take a look at the current state of it using the envcommand, which lists all of the environment variables and their settings for the currently logged in user:

Shell initialization files

Setting environment variables from within the shell is great when you need to do a one-off or just need that variable set until you logout or exit the session. However, once you do that, those variables that you manually exported will be lost since they aren't a permanent part of your shell's environment.

To make environment variable changes persist to the next session, we'll need to set them in an initialization file that gets run each time we login. Under the bash shell, this usually means setting environment variables within either the .bashrc or.bash_profile files.

Chip Castle Dot Com, Inc. is a small software shop located in beautiful Santa Rosa Beach, Florida that specializes in mobile and web development. Our philosophy is to provide the very best service possible to our clients by using available Open Source tools that are flexible and stable, while allowing us to develop software rapidly. Currently our focus is centered around development using Javascript, especially with Meteor and React.