Listing again

Do you remember the command that we used to reveal directories and files in a directory?

$ cd /Users/user/Documents 
$ ls

//Output Below


Ah yes, the ls command! Now, let's look at other ways to use it!


Other ways? Yes, we can add options to the end of commands to make them more specific.

$ cd /Users/user/Documents
$ ls -a 

//Output Below

readme.txt .secret_readme.txt

Sweet! Using the -a option, we can also see hidden directories and files, which start with a ..

Long listing

There's more to directories and files than their name, like access permissions and last modified date. Might there be an option for those as well?

$ cd Documents
$ ls -l 

//Output Below

-rw-r--r--   1 user staff      14 Sep 30 14:26 readme.txt

Fantastic! As it turns out, we can use the -l option to view a long listing of a directory.

Listing by time

At times it's handy to list the contents of a directory by the time they were last modified.

$ cd /Users/user/Movies
$ ls -t 

//Output Below


Great! The -t option will start the list with the most recently modified directories and files.

Combining options

Now that we know about those options, let's take things a step further and combine them in a single ls command!

$ cd /Users/user/Documents
$ ls -alt 

//Output Below

-rw-r--r--@  1 user  staff  14 Jun 24 23:05 .readme.txt
-rw-r--r--@  1 user  staff  14 Jun 24 22:00 readme.txt

Easy peasy! We can use multiple options at the same time by combining them into a single option.


A big part of manipulating directories and files is copying, for which we use cp, the copy command.

$ cd Documents
$ mkdir .secret
$ cp readme.txt .secret 
$ cd .secret
$ ls

//Output Below


Great job! The cp command needs the file we want to copy and the path we want to copy it to.

Psst: these things are called arguments.

Copying to an existing file

If we use the cp command with a destination file that already exists, that file is overwritten.

$ cd Documents
$ ls
leaves_of_grass.txt readme.txt
$ cp leaves_of_grass.txt readme.txt

Boom! Now we have two identical files.


So, arguments are special parameters that make commands more specific.

When we pass a file name to ls, for example, it returns all files that match the argument.

$ cd Documents
$ ls readme.txt 

//Output Below


See that? If we use a file name that exists, ls will list it; if it doesn't, we're presented with an error message.


The * sign, or wildcard character, allows us to make broad searches because it matches any character.

$ cd Documents
$ ls *.mov 

//Output Below

ls: *.mov: No such file or directory

See that? When we combine the * sign with a file extension, we can search for files with that extension.


How can we move a directory or file to a different place? Well, there's a command for that, and it works just like cp.

$ cd Documents
$ ls
$ mv readme.txt ../readme.txt
$ cd ..
$ ls

//Output Below


There it is! When moving files, we need to provide the source file and the destination.


When directories or files become obsolete, we can use rmdir or rm to get rid of them.

$ cd Documents
$ ls
$ mkdir Trash
$ touch Trash/trashme.txt
$ rm -rf
$ ls

//Output Below


Poof! We can use rmdir to remove emptydirectories andrm for files. By adding-rf to rm we can remove the directory with all the files.

Psst: we have to be careful when we remove things because there's often no way to recover them.

Introducing redirection

Redirection is all about changing the input and output of commands.

$ echo Joe > readme.txt

//Output Below


See that? The > sign redirects the output of the echo command to readme.txt.

Reading files

How can we see the contents of readme.txt, though? As always, there's a command for that!

$ echo LEAVE ME HERE > readme.txt
$ cat readme.txt 

//Output Below


That's it! The cat command reads the file and displays its contents in the output.

Counting words

Another command we'll use throughout this lesson is the word count command.

$ ls
more_words.txt  words.txt
$ wc words.txt

//Output Below

3  3  12  words.txt

See that? The wc command counts and displays the lines, words and characters followed by the file name.

Psst: we can use -l, -w, and -c as options to specifically count lines, words, or characters.

Redirecting output

We can redirect the output of a command to a file rather than the Terminal.

$ ls
$ touch trashme.txt
$ cat readme.txt > trashme.txt
$ cat trashme.txt

//Output Below


Sweet! We just created a trashme.txt file that we redirected the contents of readme.txt to.

Redirecting input

By default, input comes from the keyboard. We can use input redirection to change that, though.

$ wc < readme.txt

//Output Below

1  3  14

Great! Using the < sign, we're redirecting the contents of readme.txt as the input.

Redirecting more output

Let's look at another use of output redirection, shall we?

$ touch word_count.txt
$ wc -l readme.txt > word_count.txt
$ cat word_count.txt 

//Output Below

1  readme.txt

Great! We can output the wc -l command to the word_count.txt file rather than having it output to the terminal.

Appending to files

There's a command that allows us to append output to the end of a file.

$ echo Kittens >> favorite_things.txt
$ cat favorite_things.txt

//Output Below


Way to go! While the > sign overwrites the contents of a file, the >> command adds the output to the end of the file.


The pipe command takes the output of a command and uses it as the input of another.

$ echo LEAVE ME HERE | wc -c

//Output Below


Great! Instead of displaying the output of echo, we're using the pipe command to make it the input for the wc command.

Permissions and accessing

Every file on a computer has permission settings; while some files can't be edited, others can only be accessed by some users.

Whenever we use a computer, we have to identify with a user name.

$ whoami  

//Output Below


Good stuff! We can use the whoami command to display our user name.

Classes of permission

Every file on a computer has three classes of permission: user, group and others.

$ ls -l

//Output Below

-rwxr--r--  1  user  staff  42  Jun 24 22:00  readme.txt

Great work! We can see the permissions when we use the long format of the ls command.

Psst: characters 2, 3 and 4 refer to the permissions of user, 5, 6 and 7 refer to group, and 8, 9 and 10 refer to others.

Permissions of classes

Also, there are three different kinds of permission: reading, writing, and executing.

$ ls -l readme.txt

//Output Below

-rwxr--r--  1  user  staff  42  Jun 24 22:00  readme.txt

Great! Let's ignore the rest of the output and look at the permissions.

Psst: characters 2 to 4 (rwx) show that user can read, write, and execute. The staff group and others only have reading permissions.

Viewing permissions

We've already looked at how to view the permissions of files. Do you remember?

$ ls -l 

//Output Below

-rwxr--r-- 1 user staff 42 Jun 24 22:00 readme.txt

Yup! In order to view the permissions and long-format details, we use the -l option, either alone or with other options.

We can also see the owner: user and the group: staff.


Let's look at what the first character means in the first column of the long listing!

$ mkdir Poetry
$ touch leaves_of_grass.txt
$ ls -l

//Output Below

drwxr-xr-x  4 user  staff  68 Jun 24 22:00 Poetry
-rw-r--r--  1 user  staff   12 Jun 24 22:00 leaves_of_grass.txt

See that? Directories start with a d, as opposed to files, which have a - in the very beginning.

Changing permissions

Now, let's explore how we can change permissions with the chmod command. Let's add write permissions to notes.txt for group.

$ chmod g+w notes.txt
$ ls -l

//Output Below

-rw-rw-r-- 1 user  staff 12 10 Sep 15:47 notes.txt

Sweet! We provide the letter for the class, either + to add or - to remove a permission and, well, the permission itself.


The superuser, or root, has permissions for everything on a computer.

Look what happens when we try to access something without a permission!

$ open protected.txt

//Output Below

LSOpenURLsWithRole() failed with error -5000 for the file /Users/user/Documents/protected.txt.

See that? Because we lack the permission to open the file, we're presented with an error.

Switching users

If necessary, we can switch to root using the switch user command.

$ su 

//Output Below


Sweet! When we use su, we'll be prompted to enter the root password. When we provide a user name, we can also switch to any user.


With the sudo command, we can get around permission issues by using sudo. Let's use sudo to remove a file for which we don't have write permissions!

$ sudo rm protected.txt

//Output Below


Nice! When we use sudo, we need to enter the root password for the command to work.

What's an environment?

The Terminal knows a lot about the environment around it, like our user name, working directory, or language.

$ echo $USER

//Output Below


See that? It keeps these details in special variables that are called environment variables.

Environment variables

In a nutshell, environment variables are stored as key-value pairs.

$ env

//Output Below


See that? The env command brings up all the environment variables of the current Terminal session.

Looking at the HOME variable, HOME is the key and /Users/user is the value.


While your computer might have slightly different environment variables, it'll have a PATH variable for sure.

$ echo $PATH 

//Output Below


Great! Whenever we attempt to run a command or program, the Terminal will look in these directories for an executable file with that name.

Which path

So, where can we find the commands that we've been using so far?

$ which echo 

//Output Below


Ah yes! When we use which with a command, the Terminal gives us the location of the executable file.

Psst: we can even use the which command with itself.

Echo and the environment

As we've seen in some examples so far, we can use the echo command to view an environment variable.

$ echo $HOME 

//Output Below


Great! We just write the variable's name after echo.

Setting environment variables

In order to set an environment variable, we can use the export command. Shall we?

$ export SECRET_PASSWORD=123456789

Excellent! After the export command, we write the variable's name, an = sign and the variable's value.

Psst: export will only save the variable for this very session. When we close the Terminal window, the variable will be gone.

Modifying variables

We can also use export to modify an existing environment variable. Let's try to add something to $PATH!

$ export PATH=$PATH:/Users/user

Great work! We follow export with the environment variable to modify and assign the directory to it.

Profile files

If we want to keep these variables, we can use redirection to append the environment variable to the so-called profile file.

$ echo "export PATH=$PATH:/Users/user" >>  ~/.bash_profile

Fantastic! With >>, we can append a PATH to the end of the  .bash_profile file.

Psst: this profile file sets environment variables at the beginning of a Terminal session.

A few more useful commands

There's just a few additional commands that we should know before we'll be Terminal heroes.

How do you think can we find the manual for a command?

$ man ls

//Output Below

LS(1)                     BSD General Commands Manual                    LS(1)

ls -- list directory contents

Nice! The man command brings up a full manual for a command. Using man with ls, for example, displays all the details of the ls command.

Psst: we can quit the manual using the Q key.


The grep command helps us search for files and takes two arguments: the text and the files we're looking for.

Let's try it out here.

$ grep PywE *.txt

//Output Below


See that? If a .txt file contains that text, we're presented with the full line. grep comes in quite handy with *, the wildcard command.


Now, find does what it says on the tin - it finds file names that match a given text.

$ find . -name "*.txt"

//Output Below


Sweet! . tells the find command to look in the current directory, -name searches the names and the text in "" is, well, the text to match.


Whenever we run a program on a computer, processes that belong to the program will execute in the background.

$ ps 

//Output Below

12300 ttys000 0:00.39 -bash

See that? If we just use ps, we're presented with the processes of the current session. ps x displays all of the active processes.

Less is more

The less command is similar to cat but much more useful for longer text files.

$ less favorite_things.txt 

//Output Below

Raindrops on roses
Whiskers on kittens
Bright copper kettles
Warm woolen mittens

Awesome! With less, we can use the arrow keys to scroll through text files, revealing the full documents in the Terminal window.

Psst: again, the Q key takes us back to the Terminal session.


Using head we can specify how much of a text file we want to see.

What do you think -2 will output here?

$ head -2 favorite_things.txt

//Output Below

Raindrops on roses
Whiskers on kittens

See that? We specify the file name after head and provide an option that specifies the number of lines to display.

Psst: if we don't provide a number, the command will display ten lines.


No surprises; tail is the opposite of head. We can use it to view the contents of a file from the bottom.

What would be the output here? 

$ tail -3 favorite_things.txt
  • When I'm feeling sad,
    I simply remember my favorite things,
    and then I don't feel so bad.

See that? While the -3 option shows the last three lines, -2 displays the last two lines of favorite_things.txt.


There's also a command that allows us to sort the contents of a text file, either alphabetically or numerically.

These are the initial contents of fruit.txt:

$ sort fruits.txt

//Output Below


See that? The sort command put them in alphabetical order!


There is a great command to filter the contents of a text file and display only unique entries.

$ cat friends.txt
Mr. Robot
$ uniq friends.txt 

//Output Below

Mr. Robot

Fantastic! The uniq command filters through friends.txt and skips lines that are duplicates.