# Life in the Terminal

##### Or Bash to the UNIX kids

If you are reading this, you have been introduced to something called the Terminal on your Mac by one of your overly pushy developer friends/colleagues.

I am thinking that the conversation went something like this?

You: How can I get to that file?

Them: Just open Terminal and then $cd ~/Projects/boilerplate/ && vi .gitignore You: OMG! That is weird? What do I do? Them: Geeze, press the i key, go to this line and add <file path>/**/*. Then hit the esc key to save. To get out, type :wq, ok? Ok, we have all been there. This is weird. This is awkward. What did all of that mean? Not to mention, your terminal window is probably all stupid looking, am I right? On a developers screen, it's all cool looking. There is colored text that you can read and it's probably a little transparent. Yours, it's small, the type is hard to read, and it's white and weird looking. No wonder you don't like going in there. It's freaking weird and scary looking, I get that. In this article, I aim to help change all of that and make your interaction with the Terminal a little bit easier. ## What's the big deal anyway? What's the big deal with Terminal lately anyway? What's wrong with good 'ole GUI tools that we can download and install using the all too familiar install wizard? To sum it up in three words, it's speed, power and accessibility. Open source computing created a slew of new tools and most developers are not about creating OS specific applications to run these little apps. Not to mention, the majority of these developers were/are UNIX devs and they LIVE in the shell. A shell in computing provides a user interface for access to an operating system's services. As these tools became more mainstream with developers, especially with devs on Macs, the natural thing was to adopt the use of the Terminal. Sure, there have been some who created GUI apps for some of the more popular tools, but they never really live up to the flexibility and speed that you can get in the Terminal. Not to mention, you are now at the behest of the developer to update their GUI tool as new features are released. ## Pimp your Terminal The first step to making the Terminal easier to use it to make it easier to look at and work with. The Terminal's application preferences give us some things to start with: If you are new to Terminal, on the Startup tab, there isn't much you should really touch there. ### The Settings tab • Under Profiles select the theme that would like to use • Be sure to click the default button at the bottom so that this becomes your default theme when opening a new Terminal session #### The Text sub-tab Font: You want to update this to your preference. Monaco 14pt is a great looking font IMHO. Characters are distinct and are difficult to confuse, which is important. Text: Check and uncheck these options until the terminal looks good to you. Personally, I like to have the following checked: • Antialias text • Use bold fonts • Allow blinking text • Display ANSI colors To the right of Antialias text is a color well, I suggest changing this to a color you prefer. ANSI Colors: For the inexperienced users I suggest leaving those alone. Cursor: Select a style of cursor you like and if you want it to blink or not and you can change the cursor color. Not sure what it is, but developers for some reason really like to tweak out their Terminal to look like old skool green screen terminal computers. Myself, my first computer screen was amber, so I have a nostalgic connection to this and an amber screen has been claimed to give improved ergonomics, specifically by reducing eye strain. There is no proof to this, but who needs science? #### The Window sub-tab Title: This is what will appear in the gray bar at the top of the Terminal window. The checkboxes below, with a terminal window open, check/uncheck these options to see if they are of any value to you. Background: This is the fun one. Click on the color well for Color & Effects. This is where you can set your background to a color and adjust the transparency. There is a feature to set a background image, but this tends to be really distracting. Window size: This will set the default new open window size. And that is it for here. At this point, you should have a Terminal window that is looking pretty cool and makes you feel a little but more comfortable working with it. ## Meet Bash Ok, now that you have your Terminal window looking nice, the fun really starts as we get to know what is inside. Meet Bash. Terminal is the app that runs Bash on your computer. What is Bash? ... an acronym for the ‘Bourne-Again SHell’, a pun on Stephen Bourne, the author of the direct ancestor of the current Unix shell That's not very useful, but it is interesting. What you really need to know is that when you are looking up more information on how to do things in Terminal, you will more then likely find references to this thing called Bash. Don't get confused as the answer you are looking for is most likely there. Also, keep in mind that Bash is a fully featured environment that is able to run applications and completely interact with it's host OS. This is extremely powerful and maybe you are seeing why developers prefer this. But pay that no mind at this point. For our purposes, we are going to only go as far as the features that we need to understand. ### .bashrc, .bash_profile Probably one of the more confusing things of working with Terminal and Bash is how they are configured. Bash uses two (dot) files that are located in your computer's home directory. They are .bashrc and .bash_profile. BTW, a (dot) file is any file in the computer's file system where the name's first character is a dot. As in .bashrc. The service this provides is that the file is hidden from normal view. OSX keeps you from being able to rename a folder or file in the standard GUI for this reason. But ... we can do this from Bash. .bash_profile : read and the commands in it executed by Bash every time you log in to the system .bashrc : read and executed by Bash every time you start a subshell When using these files, there are some actions best suited for the .bashrc and others in the .bash_profile. Keeping this straight can drive you a little crazy. Luckily, there is a way that makes this all easy to manage. Simply put all your stuff in the .bash_profile file. In order to get this to work, the two files need to be linked, we do this through what is called sourcing. By placing the following code in your .bash_profile, as Terminal loads the .bash_profile it will also loop in the .bashrc file. if [ -f ~/.bashrc ]; then source ~/.bashrc fi  Ok, at this time we will just let that sit there. At this point we haven't discussed how to find files in Terminal or how to open and edit files either. Further down this tutorial I will illustrate how to edit the content of these files from within the Terminal. ## File navigation By now you should have a pretty cool looking Terminal window and have been introduced to some base concepts like Bash and it's core config files. It's time now to learn how to navigate around in this new text based world. When you first open Terminal you typically are placed in your home directory. So let's start looking and moving around. Note: in the following command examples, you will see the $ symbol. You are NOT to type the $ with the command. This is simply to illustrate that you should enter this command into the Terminal window. The first command we will learn is $ cd. What this does is Change Directory. Get it? With $cd the next symbol we will learn is the ~. This symbol is simply an alias to your home directory. So, in your Terminal, do the following: $ cd ~


Doing this will put you in your home directory. To make sure, in the Terminal enter $pwd and you should see: /Users/[your user name] Great. But at this point there is a good chance that your Terminal is not telling you very much information. You know where you are, but what's in your current directory? To list out the contents of your directory, do the following: $ ls


Great! Now you can see all the files and folders contained within your User's directory. This isn't very exciting, let's get into some fun stuff. If you are like me, you have any number of files and folders on your Desktop. All the contents of your Desktop are contained within your Desktop directory in your User's folder. So, let's change directory into Desktop by doing the following:

$cd Desktop/  And then list the items: $ ls


Remember those (dot) files? You may notice that when you do a $ls you only see files and folders that you can see in the standard OS GUI. Commands in Bash can have additional attributes passed into them called flags. To see the hidden files on your desktop pass in the -la flag like so: $ ls -la


Now, listed in the Terminal you should see hidden files and folders, also you can see permissions, file size, modified dates as well as some other information. Here is an example from my Desktop directory.

Notice is that it may be difficult to distinguish between files and folders. How can we make this easer? Passing in the -p flag with an ls command will instruct Bash to list out directories with a trailing /. To see this, do the following:

$ls -p  Great! Now we can see the contents of your Desktop directory and easily tell the difference between a file and a folder. Now we can easily see that my PeepCode content is in a directory. Continue playing with this and $ cd further into folders within your desktop.

Done? Did you $cd into a folder on your desktop and get stuck? I told you how to go in, but not how to back out. Changing directories backwards is just as easy, from within a directory, do the following: $ cd ../


That command will back you out one level from where you are. If you wanted to back out two directories, simply add another ../ like so:

$cd ../../  By now I am betting that your Terminal window is looking a bit messy. By entering the clear command, this will clean up your view and give you a nice clean Terminal window to work with: $ clear


At this point, you are doing really awesome. You have mastered some of the core commands for using Bash in the Terminal app.

### File and directory management

Next we need to learn how to add, edit and delete files and directories. While I admit, it's a little weird at first, it's actually pretty simple once you understand the commands.

#### Create / Delete files

Starting off, creating a new file is amazingly easy and very powerful. You can create any type of file with any type of file extension from Bash and the Terminal. The utility command you want to use is touch. This utility is capable of [multiple features][touch], but the one that we care about is creating a new file when one does not exist.

To do this, simply use the touch command, add on the name of the file you want to create and the file extension. To create a simple text file called "new-file" from within the Terminal, enter the following:

$touch new-file.txt  Say you wanted to create a new "index.html" file? To do so, use the following: $ touch index.html


"style.css"? Do the following:

$touch style.css  I think you are starting to get the point here. Remember when we spoke of (dot) files and that you can't create them from the default OSX GUI? This can easily be addressed in the Terminal by placing the (dot) in the name like so: $ touch .config


Remember, you can't see this file in the normal OSX GUI, so from where you are, use the ls -la command to see this file.

This brings us to the next part, how do you delete a file from the Terminal? To do this, we use the rm UNIX command which is short for remove. Using this command, we can remove that .config file we previously created by doing the following:

$rm .config  Running this command will simply delete this file and only return feedback if there is an error, for example: rm: .config: No such file or directory  Let say for example that you are not really confident with this and want to make sure that you are deleting the correct file. To do this, simply pass in the -i flag. This will instruct the command to prompt you for confirmation. Here is an example of creating a file, using that prompt flag and addressing the prompt. Desktop$ touch .config
Desktop$rm -i .config remove .config? y Desktop$


#### Create / Delete directories

Now that we have files out of the way, what about folders? In the world of Bash and Terminal, folders are actually referred to as directories. The UNIX command we are looking for is mkdir, which is short for make directory. For example, on your Desktop, let's create a new folder called foo.

$mkdir foo  Now when you do a ls -p from within your Desktop you should see this new foo/ directory we created. ProTip: You don't actually have to be in the directory you want to create a new directory in. Remember the ~ alias for your Home directory? For example, imagine you are in your Dropbox folder and you want to create a new folder on your Desktop. You could do the following: Dropbox$ mkdir ~/Desktop/foo


The next real-world thing you will run into is how to make a directory structure that is x number of levels deep. Making a directory, then changing into that directory just to make another directory is turtles all the way down.

There is a better way. When using the mkdir command, simply add on the -p flag and this will create all directories leading up to the given directory that does not already exist. If it does exist, ignore the error. Let's have fun here, run the following in your Terminal:

$mkdir -p ~/Desktop/turtles/all/the/way/down  Now that we have mastered creating directories, what about deleting them? Remember how we used the rm command to delete a file? We need to use this, but you can't simply delete a directory, we need to add on the -r flag which means to remove directories and removing the contents recursively beforehand. So to remove our turtles directory, we would run the following: $ rm -r turtles/


Let's imagine that there is a case where there would be non-existent files confirmation prompts that get in your way of deleting these directories. What is common is to add on the -f flag to force the delete like so:

$rm -r -f turtles/  For most developers, adding the -f flag is just common place and as a short hand, you can combine the -r -f flag to simply be -rf and do something like the following: $ rm -rf turtles/


Warning: Using the -f flag to force something and ignore any prompts, pay attention to what you are doing. This command will delete anything in it's path with no hesitation.

#### Move/copy/rename files and directories

Protip: When you are typing names of files and directories, start typing the first characters and then hit the tab key. Terminal will attempt autocomplete the name. If it can't hit the tab key twice and Terminal will list out all the possible options.

Now that we have created all these files and directories using the Terminal, the next obstacle to over come is to move and rename things.

Starting with the basics, renaming things in Bash uses the mv command which is short for *move*. The mv command takes two arguments, the first is the file you want to change and the second is the result you want.

$mv <source> <target>  For example, using what we have learned so far and adding in the new mv command, let's create a new file on the Desktop within a project directory and then rename it: $ cd ~/Desktop
$mkdir -p project/public/stylesheets$ cd project/public/stylesheets
$touch stylesheet.css$ mv stylesheet.css app.css


Great! Now let's say that we wanted to move that new app.css file to a new location. Remember, the mv command we used for renaming is really to move things. Since we are still in that stylesheets directory, let's move the app.css file up to the root of the public directory. To do this, use the following command:

$mv app.css ../../public/  In that example, we could also rename the file if needed, for example: $ mv app.css ../../public/style.css


Moving directories is much like moving files. For example, let's say that we created a directory at the root of project called javascripts. Oops! We need that directory to be within public. To do this, use the mv command and pass in the source and then the destination, as this example illustrates:

$mv javascripts/ public/  Renaming directories goes the same way. Say that we had a directory on the Desktop called foo and we need to rename it to be bar as shown in the following example: $ mv foo/ bar/


The last thing we will talk about here is the process of copying a file from one location to another. For this we need to use the cp UNIX utility, short for *copy*. cp is much like mv, but instead of moving the file it makes a new copy of the original in the new location. For files, the process should be familiar by now:

$cp <source> <target>  What you should also know is that in defining the target for the copied version of the file, you can also rename it. For example, and what is very common is that in a project there will be an example configuration file. It is then left up to the developer to copy that file, update the name and then edit the configurations: $ cp .config.exmaple .config


Copying directories is much like copying files, except for the fact that they have directories within, so we need to pass in the -r flag for recursive. It should also be noted that when you copy a directory, depending on how you refer to the directory in the command determines the outcome.

Let's say that we have directory_1 and then directory_2. Inside directory_1 is a file called one.html. Inside directory_2 is a file called two.html. In this first example, I will simply refer to the source and target:

$cp -r directory_1 directory_2  By doing this, the command will copy directory_1 and it's contents into directory_2. But by adding the whack / into the command on a directory, this will only copy the contents of the directory in to the new location. $ cp -r directory_1/ directory_2


This concludes the file navigation portion of this tutorial. If using Terminal is new to you and you made it this far without throwing your computer out the window, I applaud you! This is a huge step forward and you are now moving onto bigger and better things!

## Open and edit files using VI

Ok, gonna get a little rough here, but I am sure you can do it. Let's add some color to your Terminal experience. To do this, we need to add some code to your .bash_profile. The trick here is that it's difficult to open hidden files using most editors that rely on a typical finder. UNIX comes with a text editor called VI built in that you can access from the Terminal.

To get started, make sure that you are in your home directory:

$cd ~  Now, open the file in VI: $ vi .bash_profile


In your Terminal, you will have open this file in VI mode, so things are a little different. In order to add content, you need to hit the i key. This open the -- INSERT -- mode and add the following:

export CLICOLOR=1
export LSCLOLOLORS=GxFxCxDxBxegedabagaced


To save these edits, hit the esc key. To exit VI mode, type :wq. I know, all a little weird, but that's how it works. Welcome to VI.

Ok, for the fun part. If you do a ls -p here, there will be no change. To get updated to the .bash_profile to take effect, you have to do what is called 'sourcing'. To do this, run:

\$ source ~/.bash_profile


Now, enter ls -p and your directories will be a different color from your files.

## In conclusion

There is an amazing amount of material here to consume. If you are new to using the Terminal, you may have to run through these a few times to really get them locked in. But trust me, once you start down this path, there is no turning back. Running your computer from the Terminal is efficient, powerful and fast.