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 pop-up, 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 reside 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
drwxr-xr-x 2 marcus marcus 4096 Jul 10 21:04 Downloads
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
Desktop Documents Downloads FirstFolder Music Pictures Projects Public Templates Videos
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 file systems, ..
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
:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
$ 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 files. 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
Downloads
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
Downloads
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
andcd
- Create new folders with
mkdir
and new files withtouch
- Modify files with
cp
,rm
andmv
- Redirect the output of commands to files with
>
and use the output as input into a next command with|
- Read files with
less
,head
andtail
- 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.