CLI Commands
This section focuses on the command line (CLI) core commands. Typically, when working with Docker and containers, we will use some flavor of Linux OS, such as Ubuntu, Alpine, etc. Throughout this workshop, we will use Ubuntu unless stated otherwise. We will start by pulling the official Ubuntu image and launch a container using the run
command from the terminal:
docker pull ubuntu:22.04
22.04: Pulling from library/ubuntu
b91d8878f844: Pull complete
Digest: sha256:e9569c25505f33ff72e88b2990887c9dcf230f23259da296eb814fc2b41af999
Status: Downloaded newer image for ubuntu:22.04
docker.io/library/ubuntu:22.04
We use the interactive
and tty
arguments to ssh inside the container:
docker run --interactive --tty ubuntu:22.04
This will ssh into the container terminal:
root@0e52c467700c:/#
Basic CLI Commands
The ls
command lists the files and directories in the current directory (or a different directory when provided a path):
root@0e52c467700c:/# ls
bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
By default, the ls
command won’t display hidden files (e.g., starts with .
). To display all files, use the -a
argument:
root@0e52c467700c:/# ls -a
. .. .dockerenv bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
Similarly, the -l
argument will display the output in a long listing format:
root@0e52c467700c:/# ls -l
total 48
lrwxrwxrwx 1 root root 7 Jan 25 14:04 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Apr 18 2022 boot
drwxr-xr-x 5 root root 360 Feb 4 06:39 dev
drwxr-xr-x 1 root root 4096 Feb 4 06:39 etc
drwxr-xr-x 2 root root 4096 Apr 18 2022 home
lrwxrwxrwx 1 root root 7 Jan 25 14:04 lib -> usr/lib
drwxr-xr-x 2 root root 4096 Jan 25 14:04 media
drwxr-xr-x 2 root root 4096 Jan 25 14:04 mnt
drwxr-xr-x 2 root root 4096 Jan 25 14:04 opt
dr-xr-xr-x 286 root root 0 Feb 4 06:39 proc
drwx------ 2 root root 4096 Jan 25 14:09 root
drwxr-xr-x 5 root root 4096 Jan 25 14:09 run
lrwxrwxrwx 1 root root 8 Jan 25 14:04 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Jan 25 14:04 srv
dr-xr-xr-x 12 root root 0 Feb 4 06:39 sys
drwxrwxrwt 2 root root 4096 Jan 25 14:09 tmp
drwxr-xr-x 11 root root 4096 Jan 25 14:04 usr
drwxr-xr-x 11 root root 4096 Jan 25 14:09 var
The cd
command enables to change the shell working directory:
root@0e52c467700c:/# cd bin
root@0e52c467700c:/bin#
The pwd
returns the current working directory:
root@0e52c467700c:/bin# pwd
/bin
Last but not least, the ..
reference the directory above the current path:
cd ..
root@0e52c467700c:/#
Working with files and directories
The mkdir
(i.e., make directory) command enables to create a directory:
root@0e52c467700c:/# mkdir test
root@0e52c467700c:/# cd test/
root@0e52c467700c:/test#
There are many ways to create and view files via the CLI. In the following example, we will create a bash script named hellow_world.sh
that print Hello World!
. We will use the touch
command to create an empty bash script file:
root@0e52c467700c:/test# touch hello_world.sh
You can use the ls
command to confirm that the file was created:
root@0e52c467700c:/test# ls
hello_world.sh
In the CLI, the echo
command is used to print text and can be used to write text into a file with the >
symbol. As we want the bash script to print Hello World!
we will write to the file echo "Hello World!"
:
echo echo "Hello World!" > hello_world.sh
To print the content of the file, we will use the cat
command:
root@0e52c467700c:/test# cat hello_world.sh
echo Hello World!
We can now execute the file using the bash
command:
root@0e52c467700c:/test# bash hello_world.sh
Hello World!
Note: The >
symbol is used to add new text to a file. If the file already has any text, it will overwrite the previous text with the new text. To append new text, use the >>
symbol:
root@0e52c467700c:/test# echo echo "Hello World 2!" >> hello_world.sh
root@0e52c467700c:/test# cat hello_world.sh
echo Hello World!
echo Hello World 2!
root@0e52c467700c:/test# bash hello_world.sh
Hello World!
Hello World 2!
The rm
command (i.e., remove), enables to delete or remove files and folders. For example, let’s now delete the bash script we created above - hello_world.sh
:
root@0e52c467700c:/test# rm hello_world.sh
You can use the ls
command to confirm that the file was deleted:
root@0e52c467700c:/test# ls
root@0e52c467700c:/test#
Similarly, you can use the rm
command to delete folders. Let’s remove the test folder we created:
rm -rf test/
The r
arguments are used to remove directories and their contents recursively, and the f
argument to ignore nonexistent files and arguments.
Variables
Another common use case of command line functionality is the use of variables and environment variables. Assigning values to variables from the CLI is straightforward and fairly similar to other programming languages, such as R and Python, using the =
symbol. For example, let’s assign the variable x
the value 10
:
root@0e52c467700c:/# x=10
Note:Unlike R or Python, the CLI is sensitive to spaces when assigning values to variables. Using spaces would end up with error as it
root@0e52c467700c:/# x = 10
bash: x: command not found
Similarly, typing the variable name would end up with an error, as the shell interpreter is expecting a command. For example, the below code would results in an error:
root@0e52c467700c:/# x
bash: x: command not found
To refer to variables on the CLI, attach the $
sign before the variable name. For example, we will use the echo
command to print the variable x
we created above:
root@0e52c467700c:/# echo $x
10
Assign Variable to Bash Script
When building containers, we often use bash scripts as helper files. For example, the following bash script is used to install Quarto during the build time of the image with the use of variables. It has the following functionality: - Receive input from the user with the Quarto version and assign the value to a variable name QUARTO_VERSION
- Use the uname
command to evaluate the CPU type and assign it to a variable name CPU
- Use the wget
function to pull the relevant Quarto build and install it with the dpkg
function
install_quarto.sh
#!/usr/bin/env bash
QUARTO_VERSION=$1
echo "Installing Quarto version $QUARTO_VERSION"
# Identify the CPU type (M1 vs Intel)
if [[ $(uname -m) == "aarch64" ]] ; then
CPU="arm64"
elif [[ $(uname -m) == "arm64" ]] ; then
CPU="arm64"
else
CPU="amd64"
fi
TEMP_QUARTO="$(mktemp)" && \
wget -q -O "$TEMP_QUARTO" https://github.com/quarto-dev/quarto-cli/releases/download/v$QUARTO_VERSION/quarto-${QUARTO_VERSION}-linux-${CPU}.deb && \
dpkg -i "$TEMP_QUARTO" && \
rm -f "$TEMP_QUARTO"
Here is how you would execute the script:
bash install_quarto.sh "1.3.450"
Where bash will index the variables by their order of assignment starting with 1. In the above case, as we have a single variable, it will be indexed as 1 and referenced in the script as $1
Setting Environment Variables
The use of environment variables in the Docker development workflow is a very useful tool. It enables you to unify your settings with having multiple users. In addition, it enables you to parameterize your settings and avoid hard-coding some of the functionality of your image, such as the R or Python versions. We use the export
command on the CLI to set an environment variable. For example, let’s reset x
as an environment variable and assign the value 10
from the CLI:
root@0e52c467700c:/# export x=10
root@0e52c467700c:/# echo $x
10
On Linux distro, you typically use the bash .bashrc
file to add your setting and set environment variables. For example, if we want to set the x
variabe we created before as environment variable we would add the