## Introduction to Bash

### Introduction

The most common interactions with a computer nowadays are done through a Graphical User Interface (GUI). Before GUIs existed, users would interact with a computer via shell programs, a Command Line Interface (CLI) to run other programs. Despite the ubiquity of GUIs, interacting with a computer via a CLI is extremely useful for users, especially for administrative and programming tasks.

Bash (Bourne Again SHell) is arguably the most popular shell program. Bash provides us with many tools and commands that make us more productive while navigating and using our computer.

Another popular use-case for Bash is for scripting. Shell scripts provide an easy way to automate tasks. However, this article only covers how to use Bash interactively.

### Installing Bash

Bash is available for all major Operating Systems (albeit with a workaround for Windows). If you're working on a Linux or macOS computer, Bash is probably your default shell.

#### macOS

If you're using a Mac, you also get Bash by default. The version is likely pretty old, so it's advised to install Homebrew, and then use the following command to install a more recent version of Bash:

$brew install bash  For security reasons, you'll now have to whitelist your newly installed shell: $ sudo vim /etc/shells


Note: You should be prompted for your password if you're not the root user.

Ensure that /usr/local/bin/bash is in the file, if not add it to the bottom.

Finally, change the default shell of the system to the one Homebrew installed:

$chsh -s /usr/local/bin/bash  If you reopen your terminal you would be using the latest version of Bash. #### Windows 10 Getting Bash on Windows 10 is fairly straightforward granted you have a 64-bit system (the feature does not work on 32-bit machines) and you have the Fall Creators Update (not required but without it you have to turn on developer mode). You need to enable the Windows Subsystem for Linux feature. Head to the Control Panel -> Programs -> Turn Windows Features On or Off. In the popup, select the checkbox by Windows Subsystem for Linux and press OK. You will be prompted to restart your computer, if you were not then you should restart before moving on. Now you need to install Linux. Head to the Microsoft Store and search for Linux. At the top of the results, there is usually a banner to install Linux. Click on that option and you should be presented with a few Linux distributions. You can read about each one if you are interested, most people would find Ubuntu quite accessible. Once your Linux distribution is installed, you can search for it in the Start Menu, select it and see a Terminal pop up on your screen with Bash enabled by default. ### pwd Before you begin to navigate through the file system with Bash, it's good to know which directory you are currently in. In your Terminal, enter pwd. It stands for "print working directory" and it gives you the full path of your current directory. $ pwd
/home/marcus


### ls

If you would like to know what files and folders that are present in your current directory, enter the ls command.

$ls Desktop Documents Downloads Music Pictures Projects Public Templates Videos  The contents of your home folder may vary, but that won't be an issue as you follow this article. In the Unix/Linux file system, any file or folder that begins with "." is hidden from view by default. For example, if I want to consistently configure Bash when I login, then I would configure the hidden .profile or .bash_profile files that resides in my home directory. To list all files and folders, including hidden ones, we can use ls -a: $ ls -la
total 4096
drwxr-xr-x     3 marcus  marcus      4096 Jul 20 23:34 .
drwxr-xr-x    18 marcus  marcus      4096 Jul 10 21:04 ..
drwx------    15 marcus  marcus      4096 Jul 11 23:34 .cache
drwx------    11 marcus  marcus      4096 Jul 10 21:11 .config
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Desktop
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Documents
drwx------     3 marcus  marcus      4096 Jul 10 21:26 .gnupg
-rw-------     1 marcus  marcus      2310 Jul 20 17:57 .ICEauthority
drwx------     3 marcus  marcus      4096 Jul 10 21:04 .local
drwx------     5 marcus  marcus      4096 Jul 10 21:25 .mozilla
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Music
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Pictures
-rw-r-----     1 marcus  marcus      807 Jul 20 20:53 .profile
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Public
drwx------     2 marcus  marcus       442 Jul 10 21:26 .ssh
-rw-r-----     1 marcus  marcus         0 Jul 20 17:57 .sudo_as_admin_successful
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Templates
-rw-r-----     1 marcus  marcus         5 Jul 20 17:57 .vboxclient-clipboard.pid
-rw-r-----     1 marcus  marcus         5 Jul 20 17:57 .vboxclient-display.pid
-rw-r-----     1 marcus  marcus         5 Jul 20 17:57 .vboxclient-draganddrop.pid
-rw-r-----     1 marcus  marcus         5 Jul 20 17:57 .vboxclient-seamless.pid
drwxr-xr-x     2 marcus  marcus      4096 Jul 10 21:04 Videos
-rw-------     1 marcus  marcus       765 Jul 11 23:26 .viminfo


### man

Bash provides the man command, which displays the user manual for other commands.

In your Terminal, enter man ls, and you should see output like this:

Whenever you encounter an unfamiliar command, use man to see how to use it. You can scroll the manual with the Up and Down keys on your keyboard. To exit viewing a manual, press the q key.

### mkdir

Use the mkdir command to create a new folder in your current directory. The "make directory" command simply takes the name of the folder you want to create as its argument. Enter mkdir FirstFolder in your Terminal. You can confirm it exists by using ls after creating a folder.

$mkdir FirstFolder$ ls


If you would like to make a nested folder, then use mkdir with the -p flag. This tells the command to create all needed intermediary folders if they don't already exist. For example, mkdir -p SecondFolder/NestedFolder would yield the following:

$mkdir -p SecondFolder/NestedFolder$ ls SecondFolder
NestedFolder


Here you can see that both the SecondFolder and NestedFolder were created with one command.

### cd

You can move from one folder to another with the cd command. The "change directory" command takes either the absolute or relative path of the destination folder. Enter cd SecondFolder/NestedFolder/ into your Terminal. Your current directory changed from your home directory to NestedFolder. You can always confirm with pwd:

$cd SecondFolder/NestedFolder/$ pwd
/home/marcus/SecondFolder/NestedFolder


To navigate to the previous directory enter cd ... In Unix/Linux filesystems, .. used in a path refers to the directory "above" the current one. For example, SecondFolder is "above" NestedFolder. When . is used in a path, it is referring to the current directory.

So, for example, the following command will send you "up" two directories:

$cd ../..$ pwd
/home/marcus


### touch

The easiest way to create a file with Bash is through the touch command. Go back to the NestedFolder directory and enter touch first-file.txt in your Terminal to create your first file with Bash:

$cd SecondFolder/NestedFolder/$ ls -la
total 12
drwxr-xr-x     3 marcus  marcus      4096 Jul 21 16:45 .
drwxr-xr-x    18 marcus  marcus      4096 Jul 21 16:45 ..
drwxr-xr-x     2 marcus  marcus      4096 Jul 21 16:58 NestedFolder
$touch first-file.txt$ ls -la
total 12
drwxr-xr-x     3 marcus  marcus      4096 Jul 21 16:59 .
drwxr-xr-x    18 marcus  marcus      4096 Jul 21 16:45 ..
-rw-r--r--     1 marcus  marcus         0 Jul 21 16:59 first-file.txt
drwxr-xr-x     2 marcus  marcus      4096 Jul 21 16:58 NestedFolder


Now enter touch first-file.txt again in your Terminal, and then enter ls -la again as well. Your output should be similar to this:

$ls -la total 12 drwxr-xr-x 3 marcus marcus 4096 Jul 21 16:59 . drwxr-xr-x 18 marcus marcus 4096 Jul 21 16:45 .. -rw-r--r-- 1 marcus marcus 0 Jul 21 16:59 first-file.txt drwxr-xr-x 2 marcus marcus 4096 Jul 21 16:58 NestedFolder$ touch first-file.txt
$ls -la total 12 drwxr-xr-x 3 marcus marcus 4096 Jul 21 16:59 . drwxr-xr-x 18 marcus marcus 4096 Jul 21 16:45 .. -rw-r--r-- 1 marcus marcus 0 Jul 21 17:00 first-file.txt drwxr-xr-x 2 marcus marcus 4096 Jul 21 16:58 NestedFolder  You will notice that the time next to first-file.txt was updated after running touch again. While the touch command can very quickly create empty files, its core function is to update the timestamps of files. ### cp To copy a file you can use the cp command, providing it with the path of the source file, followed by the path of the newly copied file. If you wanted to copy first-file.txt into NestedFolder as second-file.txt, you would enter cp first-file.txt NestedFolder/second-file.txt. If you enter ls NestedFolder/ you would see second-file.txt: $ ls NestedFolder/
$cp first-file.txt ./NestedFolder/second-file.txt$ ls NestedFolder/
second-file.txt


To copy folders, along with their contents, use the same command as files but pass the -r (recursive) flag. Let's copy NestedFolder into FirstFolder that resides in our home directory:

$cp -r NestedFolder/ ../FirstFolder/  $ ls ../FirstFolder/
$cp -r NestedFolder/ ../FirstFolder/$ ls ../FirstFolder/
NestedFolder
$ls ../FirstFolder/NestedFolder/ second-file.txt  You have copied NestedFolder and all of its contents into FirstFolder. Note: Alternatively, if you entered cp -r NestedFolder/ ~/FirstFolder/ in the Terminal you would have gotten the same result. When ~ is used in a path, it refers to the home directory. ### rm To remove a file simply use rm and the file path. For example, rm first-file.txt would delete that file. $ ls
first-file.txt  NestedFolder
$rm first-file.txt$ ls
NestedFolder


You can remove a folder by using the -r flag. So, rm -r NestedFolder/ deletes the folder and all its contents.

$ls NestedFolder$ rm -r NestedFolder/
$ls$


Note: Items you delete with rm do not go to the Recycle Bin, in any of the major OSes. They are permanently deleted. Be very careful when deleting files and folders!

### mv

To move a file or folder from one directory to another, use the mv command along with the path of the source file/folder and the destination path. The "move" command can be used for both moving files/folders to different directories and for renaming files/folders.

In your Terminal, enter the following commands:

$ls$ mv ~/FirstFolder/NestedFolder/second-file.txt .
$ls second-file.txt$ mv second-file.txt hello-world.txt
$ls hello-world.txt  If the destination path is a folder, then the source file/folder is moved. If the destination path is a file, then the source file/folder is renamed. ### Redirects Let's say you wanted to list all the directories in the home path, but store that output into a file instead of seeing it on the screen. Bash allows for this with the redirect operator: > - it takes the output of a command and "redirects" it to a different location, typically a file: $ ls ~ > file-list.txt


In this case you would not see any output in the Terminal. Let's read our newly created file by entering less file-list.txt. The less command is used to read files.

Enter q to exit less.

The > operator overwrites files with the output of the command. To append the output of a command to the end of the file, we can use >>. Add the output of ls in our current directory to our text file, enter:

$ls >> file-list.txt  If we read the file with less once more we show see our two text files: ### Pipes If you wanted to use the output of a command as the input for another command, you would use a pipe: |. Imagine that your current directory had hundreds of file. Typing ls by itself may not be too helpful if you would like to know if hello-world.txt is in that folder. Instead of manually searching through the output of ls you can pipe the output into a next Bash command that does searches, like grep. To find out if you have a file called that contains hello in its name in a folder, enter: $ ls | grep hello


The output should be:

$ls | grep hello hello-world.txt  These pipes are like redirects in that they send the output of the command to the grep utility function, which then searches and returns any lines containing "hello". ### head and tail There are times when you want to read only the beginning or the end of a file for quick processing. The head command reads the first 10 lines of a file, and the tail command reads the last 10 lines of a file. Each command takes the file name as an argument, for example, head file-list.txt shows the first 10 lines: $ head file-list.txt
Desktop
Documents
FirstFolder
Music
Pictures
Public
SecondFolder
Templates
Videos


tail file-list.txt shows the last 10 lines of a file:

$tail file-list.txt Downloads FirstFolder Music Pictures Public SecondFolder Templates Videos file-list.txt hello-world.txt  If you would like to view the first 5 instead of 10 then you would use the -5 flag and enter head -5 file-list.txt. $ head -5 file-list.txt
Desktop
Documents
FirstFolder
Music


The numerical flag works similarly with tail, if you would like to view the last 3 lines of a file you would enter tail -3 file-list.txt.

\$ tail -3 file-list.txt
Videos
file-list.txt
hello-world.txt


### Conclusion

Bash is a cross-platform, CLI program that provides many useful commands so we can effectively do tasks on computers. Without using a GUI, you can now do the following with Bash:

• Navigate and access the file system with pwd, ls and cd
• Create new folders with mkdir and new files with touch
• Modify files with cp, rm and mv
• Redirect the output of commands to files with > and use the output as input into a next command with |
• Read files with less, head and tail
• Get the user manual for a command with man

There are many more commands available in Bash, and versatile programming language abilities so that we can script common tasks. Spending some time to learn them would be invaluable to your productivity and skill set as a developer or administrator.