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.
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.
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.
/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.
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.
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.
If you would like to know what files and folders that are present in your current directory, enter the
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
.bash_profile files that resides in my home directory.
To list all files and folders, including hidden ones, we can use
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
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
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
NestedFolder were created with one command.
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
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"
. 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
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
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.
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
second-file.txt, you would enter
cp first-file.txt NestedFolder/second-file.txt. If you enter
ls NestedFolder/ you would see
Free eBook: Git Essentials
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
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
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.
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!
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.
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.
q to exit
> 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:
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
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
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
- Create new folders with
mkdirand new files with
- Modify files with
- Redirect the output of commands to files with
>and use the output as input into a next command with
- Read files with
- Get the user manual for a command with
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.