To acquire the skills that you’ll need to deploy, administer, and maintain modern cloud technologies, you’ll need to know a solid amount of prerequisite information on the topic at hand: Linux® commands and concepts. Since many of the modern cloud technologies leverage the GNU/Linux operating system at their core, this tutorial walks you through a few basics of the Linux Command Line Interface (CLI) and prepares you to use the CLI as you work through several of our articles and tutorials on Docker and Kubernetes and our beginner Kubernetes Learning Path. If you are new to Linux, this tutorial should serve as a short introduction to its use. For the previously initiated, I hope that this tutorial reminds you of a few command concepts, and perhaps introduces you to something new.
Files and directories
We begin with a section that’s dedicated to navigating the basic file structure of a standard GNU/Linux operating system. The standard GNU/Linux operating system has a file management hierarchy that organizes the data stored on the computer. Identifying the places where specific data is stored is one of the initial lessons in beginning to understand how the operating system is structured. In an effort to keep from diminishing your existing Linux experience, I’ll save the “Introduction to the Linux File System Hierarchy” discussion for another time. Better yet, here’s a solid article that covers the File System Hierarchy in great detail. Here, we’ll assume that you know your way around a bit, so I’ll offer you a few tips (or perhaps a few reminders) on how to easily navigate. You’ll need this skill when you’re asked to edit files, navigate the file system, make changes, or observe configurations.
Changing directories with cd
The cd
command is used to change from the current directory in the terminal shell to the desired directory. This command is used very often when navigating the directory structure of a GNU/Linux file system. The syntax is as follows:
$ cd [directory]
The [directory]
parameter refers to the desired or targeted directory that you wish to change to, and the path through the file system hierarchy to this directory can be provided in a number of ways:
Absolute path
The absolute path is the “full pathway” from the root directory (commonly denoted as /
) to the targeted directory or file where it exists in the file system hierarchy. Here’s a quick example that displays the absolute path:
With the username jsmith
, on a standard GNU/Linux operating system, the absolute path to her home directory would be:
/home/jsmith
Quick tip: On a standard GNU/Linux operating system, you can get to your home directory by typing cd
at the command prompt, with no target directory specified.
The example provided above is a rather short path to the targeted directory, but in many cases, the path to a directory can be very long. In this article, we’re going to use the file system hierarchy illustrated below:
With this directory structure, the absolute path to the pacific_rose
file would be the following:
/home/jsmith/grocery_store/foods/produce/fruits/apples/pacific_rose
Relative path
The true power of a GNU/Linux operating system is in its command line interface (CLI). Performing tasks on Linux often takes you to the CLI where commands are entered. Typing full paths on the command line each time you need them can get tiresome, and this is where relative paths provide us with some support.
A relative path is defined as the path to a target directory (or file) relative to the current working directory. Again, let’s use the example above. If the current working directory is the /home/jsmith/grocery_store/foods/produce/
directory, getting to the fruits
directory is quite simple:
$ cd fruits
Since the current working directory contains the fruits
subdirectory, the above command works because is it using a relative path. You can almost characterize this as an ‘assumption’ that the operating system makes, whenever an absolute path is not specified alongside the cd
command. Now that you have navigated to the fruits
directory, you can see the full path to this directory with the pwd
command:
$ pwd
/home/jsmith/grocery_store/foods/produce/fruits
The pwd
(or print working directory) command is handy for viewing the current working directory, which is often displayed in the absolute path format. This shows us how the absolute path and the relative path can be used to navigate the file system hierarchy.
Tilde expansions
To make navigating the file hierarchy even easier (especially the file hierarchy created under a user’s home directory), standard GNU/Linux operating systems with the Bash Shell provide us with tilde expansions to help us as well. To illustrate what a tilde expansion is, let’s take a look at this example:
$ cd ~
The tilde ~
character in the above command maps to the value of the $HOME
environment variable, which is normally set to the current user’s home directory. This means that the value of this variable changes based on the user who is currently logged in. On the same system, the cd ~
command for Jane Smith would take her to the /home/jsmith
directory, whereas for Mark Jones (logged in with the username mjones
), the same command would take him to /home/mjones
directory.
Here are a couple examples of the tilde expansions in use:
~
– maps to the $HOME directory~/grocery_store
– thegrocery_store
subdirectory that exists in the $HOME directory~mjones/grocery_store
– thegrocery_store
subdirectory that exists specifically in the $HOME directory of themjones
user
Special inodes
To dig a level deeper, let’s briefly talk about inodes. As defined by Ian D. Allen, “On Unix, the collection of data that makes up the contents of a directory or a file isn’t stored under a name; the data is stored as part of a data structure called an inode.” In short, directories and files are names that map to inode numbers, and there are a number of “special inodes” that can be used to navigate the file system hierarchy. To illustrate, here are a few examples:
The ..
(double-dot) inode can be used to change to the parent directory (one level up) in the file system hierarchy:
$ cd ..
You can also move up multiple levels in the file system hierarchy by concatenating ..
(double-dot) inodes together:
$ pwd
/home/jsmith/grocery_store/foods/produce/fruits
$ cd ../ ../
$ pwd
/home/jsmith/grocery_store/foods
$
Here, we move up the file system hierarchy from the fruits
directory to the foods
directory (two levels above).
The -
(dash) allows you to change to the previous working directory:
$ cd -
In case you need to navigate from one directory to another and then back, the -
(dash) can be used to take you back to the previous working directory, no matter where in the file system hierarchy you are currently working in.
Changing directories with pushd/popd
This brings us to a second way that Linux users can navigate the file system hierarchy- the pushd
, popd
, and dirs
commands. Together, these 3 shell built-ins allow you to manipulate the directory stack, which is a list of recently visited directories. The data structure used for storing this list of recently visited directories is truly a stack or LIFO (last in, first out) data structure. pushd
changes the current directory to the targeted directory and adds this new directory to the stack, while popd
removes the directory listed at the top of the stack, then changes directories to the directory at the top of the stack.
In my personal experience, the pushd
and popd
commands are the ones I most often see in automation scripts as a way of creating a “breadcrumb trail” of directories visited. Having this list available helps when an automated task requires you to make changes to files (and directories) in a specific way or in a specific order. A previously visited directory can be “popped” off of the stack and easily revisited.
The dirs
command is a command I’ve utilized on fewer occasions, but it also very handy. It allows you to view the directory stack itself to see the list of recently visited directories. This command also has a number of options that allow you to “manage” the stack as needed. Here’s an example of using the pushd
, popd
, and dirs
commands:
Starting from the /home/jsmith/grocery_store/foods/
, we’ll use pushd
to change to the produce
directory:
$ pushd produce
The current directory is now the /home/jsmith/grocery_store/foods/produce
directory, and since we’ve used pushd
to change into this directory, it has been added to the directory stack, as show by the dirs
command:
$ dirs
/home/jsmith/grocery_store/foods/produce /home/jsmith/grocery_store/foods
$
Notice that the list of directories, from left to right, are listed by most recently visited. We’ll use pushd
again, to move into the meats
directory, then view the directory stack again:
$ pushd /home/jsmith/grocery_store/foods/meats
$ dirs
/home/jsmith/grocery_store/foods/meats /home/jsmith/grocery_store/foods/produce /home/jsmith/grocery_store/foods
$
The directory list has now grown to 3 recently visited directories. Now, if we use the popd
command, the directory listed at the top of the stack is removed, and the current directory is changed back to /home/jsmith/grocery_store/foods/produce
, as it is now the directory listed at the top of the directory stack:
$ popd
$ pwd
/home/jsmith/grocery_store/foods/produce
Another glance that the directory stack will show us that the list is back down to two recently visted directories:
$ dirs
/home/jsmith/grocery_store/foods/produce /home/jsmith/grocery_store/foods
$
For a list of options that are available to the pushd
, popd
, and dirs
commands, take a look at the Directory Stack Builtins chapter of the GNU.org Bash manual.
In the articles and tutorials to come, easily navigating directory structures will certainly be a handy skill to carry along with you, and hopefully, this brief introduction on navigating the file system hierarchy has intrigued you enough to dive in a little deeper.
Creating directories
We’ve covered navigation, now let’s quickly cover the creation of directories, which can be achieved with the mkdir
command:
$ mkdir [target]
Here in this example, [target]
is the name for the directory that you wish to create. Upon execution, mkdir
creates this directory in the current working directory (since a full path was not specified). You can also create new directories at any level of the file system hierarchy, as long as the full path can be determined and your user account has the permissions to do so. For example:
$ mkdir /home/jsmith/grocery_store/foods/produce/veggies
This creates the veggies
directory inside the home/jsmith/grocery_store/foods/produce
directory. Often, you may need to create multiple directories at the same level in the file system hierarchy, and there are even cases where an entirely new directory structure needs to be created. This is where the -p
command option is quite handy. Here’s a more advanced example:
$ mkdir -p /home/jsmith/grocery_store/foods/meats/{beef,fish,chicken,pork/{bacon,sausage}}
There are a couple of concepts at play in this example. First, the -p
option allows us to create the “path” specified, whether the directories in the path were previously created or not. Using the parentheses, you can create multiple directories at the same time. Here, we’ve created the beef
, fish
, chicken
, and pork
subdirectories inside the meats
directory (which was not previously created). Furthermore, we continued to create two more subdirectories underneath the pork
directory as well- the bacon
and sausage
subdirectories. With this, you can readily see the power of the command-line at work, creating whole new directory structures with just one command.
For more information on the mkdir
command, have a look at this lifewire article on how to create directories using mkdir.
Viewing Files and Directories
We discussed how to navigate and create directories on a standard GNU/Linux operating system. Now, let’s talk about how we can list directories, view, and edit files. Besides GUI-based applications, there are a couple of ways to view files and directories directly from the CLI.
Viewing directory contents with ls
The ls
command can be used in a variety of ways to view the contents of a directory. A simple ls
at the command prompt displays (horizontally) the contents of the current working directory:
$ ls
There are a couple of commonly used command options as well. For instance, adding a -l
flag to the command, which displays the contents of the target directory, including the file/directory name, permissions, owner, modify date, and file/directory size:
$ ls -l
The -a
option displays the contents of the directory, including hidden files, which are files primarily used for the customization and personalization of your desktop, and for application configurations:
$ ls -a
Lesser known command options for ls
The ls
command options we’ve covered so far are the most widely used. However, there are a few more options that can be just as handy as well. Here’s a quick list:
ls commmand | Description |
---|---|
ls -lh |
Combining -l with -h allows you to display the file/directory sizes in “human readable” format. |
ls -F |
Appends a / to the subdirectories listed in the output |
ls -R |
Recursively lists the contents of the subdirectories |
ls -r |
Displays the output in reverse order |
ls -lS |
Displays the output ordered by file size, with the largest files displayed first |
ls -ltr |
Combining the -l , -t , and -r options display the output ordered by modification date, with the most recent displayed last |
Viewing files with cat
One of the simplest commands for viewing the contents of a file is the cat
command. cat
, short for “concatenate”, is used to not only view the contents of a file but also for creating files by redirecting the output:
$ cat pacific_rose
This is a test file.
$
Here, the pacific_rose
file contains the ‘This is a test file.’ text. cat
displays the contents of this file directly in the terminal window, which is the quick and easy way to see what’s inside.
Combined with a redirection operator, you can use cat
to create files as well:
$ cat > granny_smith
The command above creates a new file called granny_smith
inside the current working directory.
$ cat apple1.txt apple2.txt apple3.txt > three_apples.txt
As mentioned, cat
is short for “concatenate”, and the example above illustrates how you can combine the contents of multiple files into a single file using the >
redirection operator.
Here’s a list of command flags (or options) that might also be handy to use with the cat
command:
cat -n
will display the line numbers alongside the file output.cat -e
will display the line endings and line spaces, usually with the$
character, in the file output.cat -T
will display the tab separated lines in the file output.
For more tips on how to use the cat
command, check out this LINFO article on the cat command.
Viewing files with more/less
Two additional ways to view files directly in the terminal are with the more
and less
commands. Both more
and less
allow you to view the contents of a file, pausing the file output as it fills up the screen buffer. You can choose to pause there or view the remaining output by pressing any key to continue. However, the less
command is slightly different. Though it provides the same functionality as the more
command for viewing files, with less
you also have the ability to move backwards through the output, where the more
command only allows forward viewing of the output.
Terminal text editors (vim/emacs/pico)
While learning by doing, your Linux-based study often requires you to make changes in order to create, update, and/or remove information from configuration files. Each of these actions can be achieved through the use of text editors made available on most Linux operating systems. They include:
- vi/vim
- emacs
- pico
Each editor has its own set of advantages, disadvantages, and features. Instead of advocating for any one editor over others, here’s a short list of resources that will give you tips/tricks for each one:
vi/vim:
emacs
pico
File permissions
As you begin to cover more material on your learning path, you will eventually stumble upon the need to understand file permissions. As Linux users, we have fine-grained control over what you as a user can do to the files stored on a Linux operating system. In many cases, files and directories are expected to have a certain level of permissions set in order for them to function- making a script executable, for example. So, let’s briefly cover file permissions.
$ ls -l
-rw-r--r-- 1 jdoe staff 0 Mar 15 08:30 brisket.txt
-rw-r--r-- 1 jdoe staff 0 Mar 15 08:30 ground.txt
-rw-r--r-- 1 jdoe staff 0 Mar 15 08:30 ribs.txt
-rw-r--r-- 1 jdoe staff 0 Mar 15 08:30 tar_tar.txt
In this sample directory listing, the file permissions are denoted by the -rw-r--r--
data provided for each file contained in the directory. Permissions are set on files and directories for 3 account roles: user, group, and others (i.e. everyone else). The permissions that can be granted are read (r), write (w), and execute (x). To illustrate, let’s take a look at the following table, that describes how permissions are applied to each file, based on the accounts and groups access it:
If we’re reading the file permissions for the brisket.txt
file from left to right (and omitting the first -
character), the file permissions are as follows:
user | group | others |
---|---|---|
rw (read/write) | r (read) | r (read) |
Full access permissions to a file or directory would be denoted as rwx
. In this example, the user jdoe
has read and write permissions, the staff
group has read permissions, and all others have read permissions. To understand the UGO (user, group, others) concept, I encourage you to read through this article on Getting to Know Linux File Permissions for a more in-depth look.
Changing permissions with chmod
There are cases where the permissions applied to a file need to be modified. This is where the chmod
command comes into play. As mentioned previously, bash scripts can be made executable (i.e. having the ability to ‘run’ by calling the script itself on the command line) by altering the permissions:
$ ls -l script_to_run.sh
-rw-r--r-- 1 jdoe staff 0 Mar 15 13:33 script_to_run.sh
$ chmod u+x script_to_run.sh
$ ls -l script_to_run.sh
-rwxr--r-- 1 jdoe staff 0 Mar 15 13:33 script_to_run.sh
In the above example, the script_to_run.sh
now has the +x
attribute added for the user. This means that the script is now “executable” by the jdoe
user.
$ chmod ug+x script_to_run.sh
$ ls -l script_to_run.sh
-rwxr-xr-- 1 jdoe staff 0 Mar 15 13:33 script_to_run.sh
The above example used both u
(user) and g
(group) with the chmod
command, which illustrates how you can also combine the account roles together to modify the file permissions in parallel. The +
character adds the executable attribute, and in contrast, the -
character removes it:
$ ls -l script_to_run.sh
-rwxr-xr-- 1 jdoe staff 0 Mar 15 13:33 script_to_run.sh
$ chmod ug-x script_to_run.sh # note the - character here
$ ls -l script_to_run.sh
-rw-r--r-- 1 jdoe staff 0 Mar 15 13:33 script_to_run.sh
As you see, chmod
is a very handy command for fine-tuning your file permissions as needed.
Basic Docker commands
We covered a whirlwind of command-line examples that will give you a good start with navigating the file system, viewing and creating files and directories, and customizing your terminal shell while using a standard GNU/Linux operating system. However, since this tutorial is meant to be a primer for delving into more advanced Docker, Kubernetes, and Istio tutorials and code patterns, let’s briefly list out a few Docker commands to get you started:
Building Docker images
Command | Description |
---|---|
docker images |
Lists the locally stored images |
docker rmi [IMG] |
Removes the [IMG] image from the local image repository |
docker build -t [TAG] . |
Builds a docker image from the Dockerfile in the current working directory and tags it as [TAG] |
Running Docker images
Command | Description |
---|---|
docker run --name [CNT] |
Runs a container and names it is as [CNT] |
docker run -it |
Attaches to the terminal session of the container |
docker rm -f $(docker ps -aq) |
Delete all containers |
docker ps |
List the running containers |
Shipping Docker images
Command | Description |
---|---|
docker pull |
Pulls an image from the container registry |
docker push [IMG] |
Pushes the image named [IMG] to registry |
Basic Kubernetes commands
Now that we have covered a few of the basic Docker commands, we’ll take a look at a few handy Kubernetes commands to help you along the way. Kubernetes employs kubectl
, a command-line internface tool for running commands against Kubernetes clusters. Below, you’ll find a short list of frequently used commands to update and/or extract data from your Kubernetes deployment:
Listing Kubernetes resources
Command | Description |
---|---|
kubectl get services |
Lists all kubernetes services inside the current namespace |
kubectl get pods --all-namespaces |
Lists all pods across all namespaces |
kubectl get pods -o wide |
Generates more detailed pods output from the current namespace |
kubectl describe nodes [node-name] |
Gives a brief description of the node [node-name] |
kubectl describe pods [pod-name] |
Gives a brief description of the pod [pod-name] |
Manipulating Kubernetes resources
Command | Description |
---|---|
kubectl create deployment foo --image=foo |
Deploys a single instance of foo |
kubectl create -f ./local-manifest.yaml |
Creates resources via a Kubernetes manifest file named local-manifest.yaml |
kubectl delete -f ./bar.json |
Deletes the pod as defined in the file named bar.json |
kubectl delete pod,service silver gold |
Deletes all pods and services with the names silver and gold |
For a full list of kubectl
commands see: https://kubernetes.io/docs/reference/kubectl/cheatsheet/.
Summary
This tutorial is meant to serve as a command-line warmup, “breaking the ice” as you continue to learn about container technologies like Docker, Kubernetes, and Istio. It can be a worthwhile exercise to revisit the basics prior to picking up a new skill, and I hope that the topics covered in this tutorial either refreshed your memory or helped you to pick up something new.
Next steps
After you complete this tutorial, make sure to check out the next steps in the Kubernetes Learning Path. You can also check out these resources and code patterns if you feel comfortable to play around with containers.
- Start creating Kubernetes clusters
- Connect, manage and secure microservices at scale. Run Istio on the IBM Cloud Kubernetes Service.
- Manage Docker container images in a fully managed private registry
- Code pattern: Using Istio across private and public clusters
- Code pattern: Run a Drupal website on Kubernetes
Share our content
-
- Files and directories
- Changing directories with cd
- Changing directories with pushd/popd
- Creating directories
- Viewing Files and Directories
- Viewing directory contents with ls
- Viewing files with cat
- Viewing files with more/less
- Terminal text editors (vim/emacs/pico)
- File permissions
- Basic Docker commands
- Basic Kubernetes commands
- Summary
- Next steps