Linux Basics#
This notebook serves as starting point for learning linux and the bash terminal. I highly recommend, that you run it interactively via the mybinder.org link in the top. This will allow you to execute the commands yourself.
Usually developers, system administrators, devop engineers, etc. interact with the the linux operating system via a textual interface, called the shell. The most common type of shell is called bash
. For now, the differences between these is not so important, but during troubleshooting it might help to know which shell you are using.
Linux comes with lots of preinstalled programs which make working with the shell very easy. We will look at some of them and how to use them.
This notebook is for learning purpose only. You will never interact with the shell using such a notebook. The %%bash
as well as the exclamation mark (!
) in the lines is only for the notebook. The %%bash
transforms the whole cell into a bash terminal while the !
runs only a single command via the shell.
File System#
Linux is a directory/file-based operating system.
In Linux, everything is treated as a file, including hardware devices, processes, and system configurations. The file system is organized in a hierarchical directory structure, with the root directory /
at the top. All files and directories are accessed relative to this root directory.
The home directory is a personal directory assigned to each user on the system. It serves as the default working directory when a user logs in and is where the user’s personal files, configurations, and directories are stored. The ~
is a shorthand for the home directory. It simplifies navigation.
Typically, when you open up a terminal, your session will start in the ~
folder. This is not always the case, as for the notebook here for example. The notebook and the shell open up in the folder from where they are launched. Let us look at that first.
!pwd # print the current working directory
!ls # list the contents of the current working directory
/home/runner/work/learning-notes/learning-notes/learning-notes
_config.yml dqn.ipynb kubernetes.md pca.ipynb
_toc.yml formular.ipynb links.md perceptron.ipynb
abbreviations.md images linux.ipynb rl.ipynb
assessment.md intro.md mlp.ipynb rnn.ipynb
bash.md iris.ipynb obj-detection.ipynb softmax.ipynb
cnn.ipynb k-means.ipynb optimizers.ipynb torch.ipynb
convolution.ipynb kalman-filters.ipynb p-np.ipynb virtualization.md
Next we want to see how we can navigate the filesystem. Let us start with the root and see what lies beneath it.
We can chain commands via the logical AND operator &&
. Only if the first command succeeds, the second command will be run.
!cd / && ls # change to the root directory and list its contents
bin etc lib32 opt sbin.usr-is-merged usr
bin.usr-is-merged home lib64 proc snap var
boot imagegeneration lost+found root srv
data lib media run sys
dev lib.usr-is-merged mnt sbin tmp
While the root directory is the starting point, you will seldomly operate inside it directly. You will however use it for navigation. The Github build pipeline runs this notebook inside an Ubuntu linux, such the output here will reflect a typical ubuntu installation. Ubuntu follows the Filesystem Hierarchy Standard. It is not necessary to remember them all, but it is good to have an overview of the most important directories.
/dev
: Contains device files that represent hardware devices, such as sda (hard drives), tty (terminals), and null. etc/tmp
: A temporary directory for storing files that are deleted after a reboot or after a certain period./var
: Contains variable data, such as logs (log), mail (mail), and temporary files for running services./home
: Contains the home directories of users. For example, /home/alice is the home directory for the user alice./usr/bin
: Non-essential user binaries./usr/lib
: Libraries for user applications./mnt
: A temporary mount point for attaching external storage devices like USB drives or network shares.
!whoami # shows my username
!cd ~ && pwd # change to my personal directory and show the current working directory
runner
/home/runner
As you can see, our home directory lies beneath /home/
. This is expected.
Manipulating files#
As said before, everything is file based in linux. A common task is to edit configuration files or to read logs etc.
!touch mytext.txt # create a new file called mytext.txt in the root directory
!echo "Hello" > mytext.txt # overwrite the file with the word "Hello"
!echo "World!" >> mytext.txt # append "World!" to the file
!cat mytext.txt # display the contents of the file
Hello
World!
We have seen a lot. touch
simply creates a a file. We give it the txt suffix to highlight that it is a plain text file. Although the suffix does not mean a lot. It is just an indication. Next, we used the echo command to output text. A plain echo "Hello"
would just print Hello to the standard outoutput stdout
, which is typically the terminal. The >
operator redirects the output to a file instead of displaying it to the terminal. The >>
appends to a file instead of overwriting. If a program prints a lot of debug information for example to stdout, you can use >
/>>
operator to aggregate the logs and write them into a file.
Man Pages#
Programs come very often with a manual. The man xyz
opens the manual. There you can find additional command line parameters and explanations. For the cat command you will also find that there is a –help flag which we can use.
!man cat
CAT(1) User Commands CAT(1)
NAME
cat - concatenate files and print on the standard output
SYNOPSIS
cat [OPTION]... [FILE]...
DESCRIPTION
Concatenate FILE(s) to standard output.
With no FILE, or when FILE is -, read standard input.
-A, --show-all
equivalent to -vET
-b, --number-nonblank
number nonempty output lines, overrides -n
-e equivalent to -vE
-E, --show-ends
display $ at end of each line
-n, --number
number all output lines
-s, --squeeze-blank
suppress repeated empty output lines
-t equivalent to -vT
-T, --show-tabs
display TAB characters as ^I
-u (ignored)
-v, --show-nonprinting
use ^ and M- notation, except for LFD and TAB
--help display this help and exit
--version
output version information and exit
EXAMPLES
cat f - g
Output f's contents, then standard input, then g's contents.
cat Copy standard input to standard output.
AUTHOR
Written by Torbjorn Granlund and Richard M. Stallman.
REPORTING BUGS
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
COPYRIGHT
Copyright © 2023 Free Software Foundation, Inc. License GPLv3+: GNU
GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
SEE ALSO
tac(1)
Full documentation <https://www.gnu.org/software/coreutils/cat>
or available locally via: info '(coreutils) cat invocation'
GNU coreutils 9.4 April 2024 CAT(1)
If you read the man page, you will see
cat - concatenate files and print on the standard output
Again, the standard output. This means we can also redirect the output of the file to another file using >
.
!cat mytext.txt > mytext2.txt
!cat -n mytext2.txt
1 Hello
2 World!
Pipes#
In Bash, pipes (|
) are used to pass the output of one command as the input to another command. This allows you to chain commands together to perform complex operations efficiently.
command1 | command2
command1 is executed, and its output is sent to the standard output (stdout).
Instead of displaying the output, the pipe (|) redirects it as input to command2.
command2 processes the input and produces its own output.
!ls | grep "mytext" # list all files in the current directory and filter for those containing "mytext"
!ps aux | grep "python" # list all processes and filter for those containing "python"
mytext.txt
mytext2.txt
root 824 0.0 0.1 32560 21044 ? Ss 18:32 0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root 854 0.1 0.2 44032 35672 ? Ss 18:32 0:00 /usr/bin/python3 -u /usr/sbin/waagent -daemon
root 1527 0.2 0.2 451976 35032 ? Sl 18:33 0:00 /usr/bin/python3 -u bin/WALinuxAgent-2.13.1.1-py3.9.egg -run-exthandlers
runner 2022 1.3 0.8 498552 139076 ? Sl 18:36 0:02 /opt/hostedtoolcache/Python/3.11.12/x64/bin/python /opt/hostedtoolcache/Python/3.11.12/x64/bin/jupyter-book build learning-notes --path-output book
runner 2297 10.7 0.4 768620 67740 ? Ssl 18:38 0:00 /opt/hostedtoolcache/Python/3.11.12/x64/bin/python -m ipykernel_launcher -f /tmp/tmpps2zgreh.json --HistoryManager.hist_file=:memory:
runner 2351 0.0 0.0 2808 1748 pts/0 Ss+ 18:38 0:00 /usr/bin/sh -c ps aux | grep "python" # list all processes and filter for those containing "python"
runner 2353 0.0 0.0 7084 2044 pts/0 S+ 18:38 0:00 grep python
File Permissions#
In Linux, every file and directory has a set of permissions that control who can read, write, or execute them. These permissions are assigned to three categories of users:
Owner: The user who owns the file.
Group: A group of users who share access to the file.
Others: Everyone else on the system.
Each file or directory can have the following permissions:
Read (r
):
For files: Allows viewing the contents of the file.
For directories: Allows listing the contents of the directory.
Write (w
):
For files: Allows modifying or deleting the file.
For directories: Allows creating, renaming, or deleting files within the directory.
Execute (x
):
For files: Allows running the file as a program or script.
For directories: Allows accessing the directory (e.g., using cd).
!ls -l
total 340
-rw-r--r-- 1 runner docker 834 May 13 18:35 _config.yml
-rw-r--r-- 1 runner docker 884 May 13 18:35 _toc.yml
-rw-r--r-- 1 runner docker 24278 May 13 18:35 abbreviations.md
-rw-r--r-- 1 runner docker 2078 May 13 18:35 assessment.md
-rw-r--r-- 1 runner docker 1696 May 13 18:35 bash.md
-rw-r--r-- 1 runner docker 18400 May 13 18:35 cnn.ipynb
-rw-r--r-- 1 runner docker 18814 May 13 18:35 convolution.ipynb
-rw-r--r-- 1 runner docker 13477 May 13 18:35 dqn.ipynb
-rw-r--r-- 1 runner docker 4370 May 13 18:35 formular.ipynb
drwxr-xr-x 2 runner docker 4096 May 13 18:35 images
-rw-r--r-- 1 runner docker 1206 May 13 18:35 intro.md
-rwxr-xr-x 1 runner docker 4930 May 13 18:35 iris.ipynb
-rw-r--r-- 1 runner docker 8346 May 13 18:35 k-means.ipynb
-rw-r--r-- 1 runner docker 12301 May 13 18:35 kalman-filters.ipynb
-rw-r--r-- 1 runner docker 6069 May 13 18:35 kubernetes.md
-rw-r--r-- 1 runner docker 505 May 13 18:35 links.md
-rw-r--r-- 1 runner docker 13369 May 13 18:35 linux.ipynb
-rw-r--r-- 1 runner docker 16728 May 13 18:35 mlp.ipynb
-rw-r--r-- 1 runner docker 13 May 13 18:38 mytext.txt
-rw-r--r-- 1 runner docker 13 May 13 18:38 mytext2.txt
-rw-r--r-- 1 runner docker 10068 May 13 18:35 obj-detection.ipynb
-rw-r--r-- 1 runner docker 13307 May 13 18:35 optimizers.ipynb
-rw-r--r-- 1 runner docker 11359 May 13 18:35 p-np.ipynb
-rw-r--r-- 1 runner docker 14891 May 13 18:35 pca.ipynb
-rw-r--r-- 1 runner docker 16219 May 13 18:35 perceptron.ipynb
-rw-r--r-- 1 runner docker 17393 May 13 18:35 rl.ipynb
-rw-r--r-- 1 runner docker 12666 May 13 18:35 rnn.ipynb
-rw-r--r-- 1 runner docker 4262 May 13 18:35 softmax.ipynb
-rw-r--r-- 1 runner docker 12570 May 13 18:35 torch.ipynb
-rw-r--r-- 1 runner docker 3957 May 13 18:35 virtualization.md
An example output looks like this:
-rwxr-xr-- 1 user group 1234 May 12 12:00 file.txt
The first character (
-
) indicates the type of file (-
for regular file,d
for directory).The next nine characters are the permissions:
rwx
(Owner): Read, Write, Execute.r-x
(Group): Read, Execute.r--
(Others): Read only.
Using chmod
, we can modify the permissions.
Lets change the permissions for mytext.txt
Add, remove, or set permissions using u (owner), g (group), o (others), or a (all). Use + (add), - (remove), or = (set).
!chmod a=w mytext.txt # change permissions to allow all users to write
!ls -l mytext.txt
!chmod a=r mytext.txt # change permissions to allow all users to read
!ls -l mytext.txt
!chmod a+x mytext.txt # change permissions to allow all users to execute
!ls -l mytext.txt
!chmod a-x mytext.txt # change permissions to remove execute permissions for all users
!ls -l mytext.txt
!chmod u+x mytext.txt # change permissions to allow the user (owner) to execute
!ls -l mytext.txt
!chmod g+x mytext.txt # change permissions to allow the group to execute
!ls -l mytext.txt
!chmod o+x mytext.txt # change permissions to allow others to execute
!ls -l mytext.txt
--w--w--w- 1 runner docker 13 May 13 18:38 mytext.txt
-r--r--r-- 1 runner docker 13 May 13 18:38 mytext.txt
-r-xr-xr-x 1 runner docker 13 May 13 18:38 mytext.txt
-r--r--r-- 1 runner docker 13 May 13 18:38 mytext.txt
-r-xr--r-- 1 runner docker 13 May 13 18:38 mytext.txt
-r-xr-xr-- 1 runner docker 13 May 13 18:38 mytext.txt
-r-xr-xr-x 1 runner docker 13 May 13 18:38 mytext.txt
As you can see, there are multiple ways to set permissions for the files. Setting correct permissions is an important tasks, since you do not want your configuration to be manipulated by everyone. Usually, they are heavily restricted, such that only an administrator can change them.
While the symbolic way is one option to change the permission, there is another more effective way, the numeric mode.
4 = Read (r)
2 = Write (w)
1 = Execute (x)
Each user/group/all permission is assigned a combiniation of these three numbers. This is usually a lot simpler, sice you can assign the correct permissions in one step:
!chmod 777 mytext.txt # change the permissions of mytext.txt to read, write, and execute
!ls -l mytext.txt # list the details of mytext.txt to see the new permissions
!chmod 644 mytext.txt # change the permissions of mytext.txt back to read and write for the owner, and read for others
!ls -l mytext.txt # list the details of mytext.txt to see the new permissions
-rwxrwxrwx 1 runner docker 13 May 13 18:38 mytext.txt
-rw-r--r-- 1 runner docker 13 May 13 18:38 mytext.txt