Sample Video Frame
08: Bash Basics
OSX Troubles
If you are using OSX (macOS) you may be forced to use a different shell called zsh. You should be able to use all of these commands with zsh, but if you want to use bash then you can force OSX to use bash. Type this command in Terminal:
chsh -s /bin/bash
Then log out of your computer completely and log back in. If it worked then you should be able to type:
echo $SHELL
That command should print out "/bin/bash" and you're done.
Getting Help
Usually you can get help for a command by adding either -h
or --help
to the command like this:
man -h
This tends to fail with some commands so the other way to get help is to use the man
command to print out the "manual" for the command:
man ls
This will print out the entire documentation for the ls
command. I usually try -h
first, and if that doesn't work then I use man
.
Where Are You?
On OSX your real home directory is /Users/username
where "username" is whatever you use to log in. Mine is therefore named /Users/zed
, but on Linux they use /home/username
instead. On Linux my home directory is /home/zed
.
When you start a terminal you start off in this home directory. Try this command to see where that is:
pwd
This prints out your working directory (pwd means print working directory) and tells you are in the disk drive. You should then look to the left and see that bash is printing out the same information for your command prompt. Here's mine:
Zeds-iMac-Pro:ljsthw zed$ pwd
/Users/zed/Projects/ljsthw
The difference is pwd
prints out the entire path to your current location, so in my case this is /Users/zed/Projects/ljsthw
. On the prompt though it only prints the name of the current directory, which is ljsthw
. Bash also prints out other useful information such as my computer name (Zeds-iMac-Pro
), and my current username (zed
).
What's In Here?
When you save a file you're working on it is written to the disk in your home directory. The problem is it's saved "somewhere" in your home directory and you have to go find it. To do that you need two commands: one to list a directory and one to change to a directory (which you learn later).
Each directory has a listing of its contents which you can see with the ls
command:
ls
ls Desktop
ls ~
In the above examples I first list the contents of the current directory. The "current directory" is also the "working directory" from the "print working directory pwd
" command. It's simply wherever your bash shell says you are in the prompt or when you run pwd
. Next, I list the contents of the Desktop directory, which should be files and "folders" sitting on your Desktop.
Finally, I use a special character ~
(tilde) to list the contents of my home directory. On Unix systems (Linux and OSX) the ~
character is short for "My Home directory." Look at this example to see how that works:
Zeds-iMac-Pro:~ zed$ pwd
/Users/zed
Zeds-iMac-Pro:~ zed$ ls /Users/zed
# ... lots of output
Zeds-iMac-Pro:~ zed$ ls ~
# ... the same output
You can see here that the pwd
command says I'm in /Users/zed
on my OSX computer, and if I use ls /Users/zed
or ls ~
then I get the same output.
Files, Folders, Directories, and Paths
Before I cover how to move around your directories I need to explain three interconnected concepts. Files are what holds your data and they will have names like mydiary.txt
or ex1.js
.
Those files are located inside directories which you've seen such as /Users/zed
. Directories can go "deeper", meaning I can put directories inside directories inside directories with files inside those. I could have the a directory called /Users/zed/Projects/ljsthw
and if I put my ex1.js
file in there it would live at /Users/zed/Projects/ljsthw/ex1.js
.
That last part is called the "path", and you can think of it like a path through a maze that leads to a special room. You can also combine the concept of ~
(tilde) to replace /Users/zed
and then the path becomes ~/Projects/ljsthw/ex1.js
.
If you have Directories, Files, and Paths when you use bash then how does that map to "Folders" when you're looking through a Graphical File Browser. I say "Graphical File Browser" because bash works on OSX and Linux, and how you view files graphically is different on both of them. On OSX this is the "Finder Window" you get when you click on a folder on your computer.
There is no difference between "Folder" and "Directory". They are the same thing, so if you traverse a series of mouse clicks in Finder to access "Folders", then you can use that path of clicks to list the contents of that as a "directory". They are literally the same thing, and it's important for you to get this idea.
One way to learn that they are connected is to use your Finder to create folders, and place small files in them, then use bash to find these files and open them. Think of it like a treasure hunt in your Terminal. Before you can do that you'll need the cd
command for "changing directories".
Moving Around
You know how to list a directory from where you are in bash:
ls ~/Projects/ljsthw/
You can also change to that directory with the cd
command:
cd ~/Projects/ljsthw/
pwd
This won't magically work for you since you never created the directory "Projects" and "ljsthw", but take the time now to make those in your Finder window (Create Folder is what you want) and then use cd
like I demonstrate.
The idea with bash and cd
is you are moving around in the directories as if they're small rooms with connecting corridors. If you've ever played a video game then you know what this is like. Your cd Projects/ljsthw
command is like moving your character into the room named Projects
and then walking into the next room ljsthw
.
Take the time right now to continue using ls
, pwd
, and cd
to explorer your computer. Make directories (folders) in your Finder window and then attempt to access them from inside bash until your brain makes the connection. This might take a while since you're trying to map graphical interface you've used for years to textual elements that are new.
Relative Paths
Imagine you did this:
cd ~/Projects/ljsthw
Now you're stuck in this ljsthw
directory, so how you "go back"? You need the relative path operator:
cd ..
The ..
(dot dot) says "the directory above my current directory", so in this case since Projects
is "above" ljsthw
it makes ..
mean Projects
. These two commands are the same then:
cd ..
cd ~/Projects
If Projects
contained two directories named ljsthw
and mycode
, you could do this
cd ~/Projects/ljsthw
# oops I meant mycode
cd ../mycode
If you're still thinking of cd
like moving between rooms in a building then ..
is how you go back the way you came.
Creating and Destroying
You don't have to use any graphical interfaces to create directories. You can use commands, and for decades this was how you interacted with files. The commands for manipulating directories and files are:
- mkdir -- Creates a new directory.
- rmdir -- Removes a directory, but only if it's empty.
- rm -- Removes anything. Use
rm -rf
to remove a directory no matter what. - touch -- Makes a new empty file.
I'm purposefully not fully explaining these commands because I want you to figure them out and learn them on your own. Figuring out these commands helps you own your own education and makes it stick. Use what you know so far to learn the commands, such as using man rm
to read the manual.
Hidden Files
On Unix systems like OSX and Linux there's a slight "gotcha" when it comes to files. Imagine you attempt to delete a diretory:
Zeds-iMac-Pro:~ zed$ rmdir Projects
rmdir: Projects: Directory not empty
You get this error that Projects
is not empty, and that's because the ljsthw
directory is in there, so you try this:
Zeds-iMac-Pro:~ zed$ rmdir Projects/ljsthw
rmdir: Projects/ljsthw: Directory not empty
What? You totally emptied that directory out so how is "not empty"? Try this:
cd Projects/ljsthw
ls -la
Now you see this weird new file the dreaded .DS_Store
. This would only be on the OSX system, but any Unix system considers a file starting with .
(dot) to be a special file it won't show you normally. To see it you have to use the ls -la
command to list out all of the files, even hidden ones.
Flags and Arguments
Commands have a structure that goes something (but not exactly) like this:
command flags arguments
The command is the word you type, like ls
, cd
, or cp
. The "flags" are things you write to configure how the command should run, and start with -
or --
. This is what you did with ls -la
. You added the flag -l
and -a
to the ls
command to tell it to "list all" files. You don't have to give each flag as an individual -
when they are single letters. You can combine them as I did with -la
.
The other kind of flag is the --blah
style, and is usually only used as an alternative that's more readable compared to the single letter versions. Sometimes these flags are also written as --var=value
style.
Then you have the "arguments", which are space delimited pieces of information you give to the command. With cp
this is two arguments that give the source and destination of the files:
cp ex1.txt ex1.js
In this example the file ex1.txt
is the first argument, and the ex1.js
is the second argument, so this would copy the first argument to the second argument.
Finally you can combine these, so if I want to copy an entire directory and its contents I do:
cp -r ljsthw backup
The -r
option means "recursive" which is a fancy computer science way of "go down into the directory". Doing this will make a whole copy of ljsthw
to backup
.
Copy and Move
You can also copy a file and move a file, or directory. Continue with your self-education and attempt to learn about and use these new commands:
- cp -- Copies files.
- mv -- Moves files.
Remember that you can use man cp
and man mv
to study the commands. These commands are also the first ones to take multiple arguments, which you just learned about.
Environment Variables
The commands so far are clearly configured using the -
(dash) and --
(dash dash) style options, but many of them are also configured using a slightly hidden thing called "Environment Variables", or "env vars" for short. These are settings that live in your shell and are not visible immediately, but work to configure persistent options for all commands. To see your environment type this:
env
There's also a handy command called grep
which takes the output of one command and filters it to only show what you want, so try this:
env | grep PATH
Now you should see only the PATH
variable's settings. What's that |
(pipe) character doing? It's called a "pipe" and you can think of it like a...pipe. Seriously, it's a pipe taking the output of one command and sending it to the input of another. They're very handy and you'll see me use them a lot in the course, but they're also very simple. Output goes to input. That's it. Like a pipe.
Running Code
Finally! The entire point of this whole lesson! How do you run code? Imagine you have a JavaScript file named ex1.js
and you want to run it to see its output (and see if it works):
node ex1.js
As you can see, \node
is the JavaScript "runner" and it simply loads the ex1.js
file and runs it. Node also takes many options, so try this:
node --help
man node
If everything is setup correctly your man node
command should display a more detailed explanation of what's shown in the \node --help
command.
The other command you'll use often is the npm
command, which installs JavaScript libraries for your project:
npm install polka
If you create a directory named testproject
, cd into it, and run this command, you'll install the polka webserver. We'll use this command more later, but for now that's mostly what you need to know.
Common Key Sequences
There's two key sequences you'll need to know when you work with your software:
- ctrl-c -- Aborts a program.
- ctrl-d -- Closes your input, usually exiting a program.
These aren't totally reliable ways to abort a program, since it's possible for programmers to catch them and prevent you from exiting. For example, here's the GNU bc command being very helpful (not):
Zeds-iMac-Pro:~ zed$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
2 + 5
7
(interrupt) use quit to exit.
quit
So helpful. Thank you for telling me that I can't use CTRL-c but have to use "quit" to quit. I'm sure someone spent many hours doing the work to catch the CTRL-c key sequence just to tell me to then type quit instead of just...quitting for me.
Despite this, usually these two key sequences will get you out of a program, or print a message telling you how to do that.
Useful Developer Commands
There are three commands that come up as useful developer commands:
- curl -- If you give this a URL from a browser it will usually display the raw text. You might want to do
curl -L URL
to tell curl to follow redirects. - ps -- Lists all of the running processes on your computer.
- kill -- Lets you kill a process. Use this if it's running and you can stop it:
kill -KILL PID
.
Curl is useful when you're working on a website and you need to make sure you're getting the real output. You run it like this:
curl http://127.0.0.1:5000
We'll get into what all of that means later, but just remember curl
is your tool for looking at the full text of a website.
The ps
command lists the processes that are currently running. A process is simply one of the programs you've ran, and this situation comes up usually when you have multiple terminal windows or multiple tabs open. You might have a command that you can kill with ctrl-c so you can use ps
to find it, and kill
to kill it. First do this:
Zeds-iMac-Pro:~ zedshaw$ ps
PID TTY TIME CMD
677 ttys000 0:00.03 /Applications/iTerm.app/Contents/MacOS/iTerm2
679 ttys000 0:00.05 -bash
1684 ttys001 0:00.03 /Applications/iTerm.app/Contents/MacOS/iTerm2
1686 ttys001 0:00.01 -bash
That will list all of the processes running at the moment, and you can see my output shows a couple of terminals open. The PID is the "process ID" and that number lets you kill the process from another window. Just grab the PID, go to a new window, and type:
kill -KILL 679
You can also use kill -TERM PID
to be a little nicer about it. Usually I try TERM
and if that doesn't work I do KILL
.
Crash Landing
This is definitely not enough to be a master of the Unix command line, but it should be enough to understand what I'm doing in the rest of the course and to have enough to follow along. I highly recommend you take notes while you watch me work and write down any commands you see me use that you're not familiar with.
Register for Learn JavaScript the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.