linux_introduction/essential/readme.md

1445 lines
71 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Introduction to Linux
## Where does Linux originate from?
* The spiritual mother of Linux is [Unix](https://en.wikipedia.org/wiki/Unix).
* [POSIX](https://en.wikipedia.org/wiki/POSIX) is not an OS in itself but a **standard**.
* Which OS's are [POSIX compliant](https://en.wikipedia.org/wiki/POSIX#POSIX-oriented_operating_systems)
## Who is behind this project?
* Who is [Richard Stallmann](https://en.wikipedia.org/wiki/Richard_Stallman)?
* Who is [Linus Torvalds](https://en.wikipedia.org/wiki/Linus_Torvalds)?
## What is the deal with 'GNU-slash-Linux'?
* [GNU/Linux](https://en.wikipedia.org/wiki/GNU/Linux_naming_controversy) controversy
* What is a [kernel](https://en.wikipedia.org/wiki/Kernel_(operating_system))
* What does [GNU](https://www.gnu.org/software/) bring to the table?
* What's the deal with [userspace and kernelspace](https://unix.stackexchange.com/questions/137820/whats-the-difference-of-the-userland-vs-the-kernel)?
* [userspace](http://www.linfo.org/user_space.html)
* [kernelspace](http://www.linfo.org/kernel_space.html)
![Linux kernel](../assets/linux_kernel.png)
## Where can you *get* some Linux?
* You probably already have a Linux computer running at [home](https://opensource.com/article/19/8/everyday-tech-runs-linux)!
![Timeline](../assets/distro_timeline.png)
## Debian
* [Reasons](https://www.debian.org/intro/why_debian) to choose Debian.
* Why is Debian called [the universal operating system](https://www.reddit.com/r/debian/comments/22j0wf/so_why_debian_is_called_the_universal_operating/)?
* [comparison](https://en.wikipedia.org/wiki/Comparison_of_instruction_set_architectures) of CPU architectures
* [download](https://www.debian.org/distrib/netinst) Debian
# How to create a virtual machine
In order to run virtual machines, or VM's, we need a **host** program.
One of the most popular ones out there is called `virtualbox`.
It should be installed on your machine but in case it's not you can download it [here](https://www.virtualbox.org/wiki/Downloads).
If you **expand** the section below you'll see a step by step walk-through of a VM creation in virtualbox with some notes on each step with best practice pointers.
<details>
<summary>Expand me...</summary>
**Nice!**
1. Name your machine and select *linux* if it's not chosen automatically.
![virtualbox setup](../assets/2022-02-18-122703_1920x1080_scrot.png)
1. Set the amount of RAM for your machine.
This can be anything between an absolute minimum and your physical machine's limit.
You can't *magically* use more RAM than physically available!
![virtualbox setup](../assets/2022-02-18-122833_1920x1080_scrot.png)
1. You need a virtual hard drive to store the OS and all your data to.
![virtualbox setup](../assets/2022-02-18-122930_1920x1080_scrot.png)
1. The format doesn't matter that much.
I always go for the default one.
![virtualbox setup](../assets/2022-02-18-122943_1920x1080_scrot.png)
1. Most of the time you'll want dynamic size meaning the disk **file** will only take up as much **space** as it needs.
For example, if you set a size of 50GB for your disk and your OS plus personal files take up 12GB, the actual space this image takes op on the physical disk of your **host** will be about 12GB.
![virtualbox setup](../assets/2022-02-18-122951_1920x1080_scrot.png)
1. We'll soon discover **how much space** a basic Linux installation takes up but for now I would recommend the following.
* **with** a graphical environment: 20GB
* **without** a graphical environment: 10GB (minimal/server/headless install)
![virtualbox setup](../assets/2022-02-18-123011_1920x1080_scrot.png)
1. By default your machine will have only **one** CPU core but you can add more via the settings.
This is something you can change whenever you need more processing power but the same rule as with the RAM applies, it's not a magical way to add resources to your machine.
![virtualbox setup](../assets/2022-02-18-123047_1920x1080_scrot.png)
1. Last but not least we need to insert the installation disk into the virtual machine and boot it up!
![virtualbox setup](../assets/2022-02-18-123121_1920x1080_scrot.png)
</details>
# Breakdown of the Debian installation
All right, enough talking, let's get started!
I'll install a full blown and modern graphical Debian machine and I would like you to **not** do it yourself but take **notes** on each step so you'll be able to reference your notes later **when** I ask you to install a machine yourself.
Below is a gain a step by step walk through with some of my tips but a more details guide can be found in the [Debian Administrator Handbook](https://debian-handbook.info/browse/stable/sect.installation-steps.html).
This book is a real *bible* of information and I highly advise you to read through it.
My most important notes would be the following.
* **Read** each section carefully and you'll know what to do.
* Don't set a root password but use `sudo` instead.
* Don't install a graphical environment if you don't need one.
It's a lot easier to add one later than to remove it.
* Don't forget to install `grub` at the end otherwise your installation will not be able to boot.
You *can* recover from this mistake with [supergrub2](https://www.supergrubdisk.org/super-grub2-disk/) but that's for an other day.
<details>
<summary>Expand me...</summary>
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_32_45.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_32_57.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_33_07.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_33_11.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_33_18.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_33_21.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_33_27.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_34_18.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_34_29.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_34_34.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_34_39.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_34_52.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_34_55.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_35_01.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_35_17.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_35_20.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_35_23.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_35_27.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_35_32.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_37_53.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_37_57.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_38_00.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_38_02.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_39_44.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_39_53.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_40_07.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_49_11.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_49_15.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_50_26.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_50_38.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_50_55.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_51_07.png)
</details>
# Exercise
OK, now it's up to you!
Please install a Debian machine with the default graphical environment.
Once installed, take some time out to explore the system.
Which software is installed by default?
How can you tweak the system settings such as language, keyboard, networking?
Can you install extra software?
# Quick look at an idle system
You can inspect the system by running the *gnome task manager*.
It lists all your running processes, sorted by CPU percentage, in the first tab which can give you a good idea of what's happening on your system.
Note that an idle system uses almost **no resources**!
Plus, a fresh install, with quite a few essential programs such as a browser, music player, text editor, etc only takes up about 5GB of disk space!
This is mind blowing compared to a windows installation.
How is this possible?
That's the magic of a good package manager!
<details>
<summary>Expand me...</summary>
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_53_40.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_54_33.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_54_41.png)
</details>
# Package managers
What is a [package manager](https://en.wikipedia.org/wiki/Package_manager)
## Graphical installation
Modern Linux has come a long way and it's now quite usable without any command line knowledge.
We can install extra software from the graphical environment if we want.
Let's look for `vlc`, a popular open source video player.
When we look for it from `activities` we *see* a reference to it via the `software` program.
If we click on it we'll be take to a sort of *app or play store* where we can choose to install or uninstall programs.
Because adding and removing software from our machine is quite *invasive*, we need to **prove** we have the right to do so.
A prompt will pop up where you'll need to input **your** password.
If your password does not work, you probably set a `root` password and you should use that one instead.
<details>
<summary>Expand me...</summary>
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_51_24.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_52_06.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_52_15.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_52_36.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_52_46.png)
![Debian installation](../assets/VirtualBox_debian_18_02_2022_12_52_53.png)
</details>
## Command line installation
```bash
waldek@hellodebian:~$ htop
-bash: htop: command not found
waldek@hellodebian:~$ apt install htop
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
waldek@hellodebian:~$ sudo apt install htop
[sudo] password for waldek:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Suggested packages:
lm-sensors strace
The following NEW packages will be installed:
htop
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 127 kB of archives.
After this operation, 328 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bullseye/main amd64 htop amd64 3.0.5-7 [127 kB]
Fetched 127 kB in 0s (2,030 kB/s)
Selecting previously unselected package htop.
(Reading database ... 141359 files and directories currently installed.)
Preparing to unpack .../htop_3.0.5-7_amd64.deb ...
Unpacking htop (3.0.5-7) ...
Setting up htop (3.0.5-7) ...
Processing triggers for mailcap (3.69) ...
Processing triggers for desktop-file-utils (0.26-1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...
Processing triggers for gnome-menus (3.36.0-1) ...
Processing triggers for man-db (2.9.4-2) ...
waldek@hellodebian:~$
```
![htop](../assets/VirtualBox_debian_18_02_2022_13_18_25.png)
![htop](../assets/VirtualBox_debian_18_02_2022_13_18_51.png)
The *menu bar* at the bottom shows you can press **F10** to quit.
This does not work because of a shortcut of gnome-terminal!
You can deactivate this shortcut in the preferences though.
But pressing **q** also exits the program.
![htop bug with gnome-terminal](../assets/VirtualBox_debian_18_02_2022_13_19_35.png)
## Adding a secondary desktop environment
During the initial installation we where offered a choice of desktop environments to install.
This menu was an actual program called `tasksel` we can run again to add different ones!
As it's a program that can heavily modify the system, we need administrator privileges.
```bash
waldek@hellodebian:~$ sudo tasksel
[sudo] password for waldek:
```
![tasksel](../assets/VirtualBox_debian_18_02_2022_13_21_33.png)
![tasksel](../assets/VirtualBox_debian_18_02_2022_13_22_33.png)
![tasksel](../assets/VirtualBox_debian_18_02_2022_13_22_47.png)
![tasksel](../assets/VirtualBox_debian_18_02_2022_13_23_57.png)
# Changing the runlevel
The **first** process started by the kernel can be discover by `htop` and is `/usr/sbin/init`.
This is rather vague but we can find out a *bit* more about this program via `ls` which we'll get into more detail later.
For now just have a look at the output of the following commmand.
```bash
waldek@hellodebian:~$ ls -l /usr/sbin/init
lrwxrwxrwx 1 root root 20 Jul 13 2021 /usr/sbin/init -> /lib/systemd/systemd
waldek@hellodebian:~$
```
Now, what *is* this [systemd](https://en.wikipedia.org/wiki/Systemd)?
And more importantly, *how* do we interact with it?
For now just accept that the main program to communicate with `systemd` is `systemctl`.
A quick look at the `man` pages gives us the following.
```bash
SYSTEMCTL(1) systemctl SYSTEMCTL(1)
NAME
systemctl - Control the systemd system and service manager
SYNOPSIS
systemctl [OPTIONS...] COMMAND [UNIT...]
DESCRIPTION
systemctl may be used to introspect and control the state of the "systemd" system and service manager. Please refer to systemd(1) for an
introduction into the basic concepts and functionality this tool manages.
```
```bash
waldek@hellodebian:~$ sudo systemctl set-default multi-user.target
[sudo] password for waldek:
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
waldek@hellodebian:~$ sudo reboot now
```
After the reboot you'll be confronted with the following screen.
Don't stress, your machine is not broken!
It's just running in a more *minimal* mode.
You can log in just as with the graphical login window but you'll only have a command line to interact with the machine.
A quick look at `htop` tells us not a lot of stuff is running, just the bare minimum.
![minimal runlevel](../assets/VirtualBox_debian_18_02_2022_13_40_00.png)
![minimal runlevel](../assets/VirtualBox_debian_18_02_2022_13_40_11.png)
To *undo* this change and regain the graphical interface again you can run the following commands.
```bash
waldek@hellodebian:~$ sudo systemctl set-default graphical.target
[sudo] password for waldek:
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/graphical.target.
waldek@hellodebian:~$ sudo reboot now
```
# Exercise
Please create a second virtual machine and install a **minimal** Debian.
Minimal means **no graphical environment**.
I advise you to **not** set a root password.
Once this machine is up and running, install a few programs.
The only one we saw up until now is `htop` but maybe try out `bmon`, `elinks` and/or `ranger`.
Once these are installed have a look at the running services and programs via `htop` and compare it to both your graphical installation **and** your graphical install but running in `multi-user.target`.
# Guest additions
Let's make our user experience a bit nicer.
Virtual machines can *integrate* with the host machine more fluently when you install the guest additions in the VM.
It's a three step process.
1. install the required packages to build the guest additions in you VM
1. insert the guest additions CD into your VM
1. run the correct script from the CD
The dependencies can be installed as follows.
First you `update` your package list, next you install three packages.
* `build-essential`
* `dkms`
* `linux-headers-$(uname -r)`
The *third* package name is a bit weird looking no?
This is a bit of command line kung fu.
The actual *name* of the package is as follows.
```
waldek@hellodebian:~$ echo linux-headers-$(uname -r)
linux-headers-5.10.0-11-amd64
waldek@hellodebian:~$
```
The `$(uname -r)` is a call to a program called `uname` with the option `-r`.
We'll go more into detail on this later.
```
waldek@hellodebian:~$ sudo apt update
Hit:1 http://deb.debian.org/debian bullseye InRelease
Hit:2 http://deb.debian.org/debian bullseye-updates InRelease
Hit:3 http://security.debian.org/debian-security bullseye-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
waldek@hellodebian:~$ sudo apt install build-essential dkms linux-headers-$(uname -r)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
binutils binutils-common binutils-x86-64-linux-gnu dctrl-tools dpkg-dev fakeroot g++ g++-10 gcc gcc-10 libalgorithm-diff-perl
libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan6 libatomic1 libbinutils libc-dev-bin libc-devtools libc6-dev libcc1-0 libcrypt-dev
libctf-nobfd0 libctf0 libfakeroot libgcc-10-dev libitm1 liblsan0 libnsl-dev libstdc++-10-dev libtirpc-dev libtsan0 libubsan1
linux-compiler-gcc-10-x86 linux-headers-5.10.0-11-common linux-headers-amd64 linux-kbuild-5.10 linux-libc-dev make manpages-dev patch
Suggested packages:
binutils-doc debtags debian-keyring g++-multilib g++-10-multilib gcc-10-doc gcc-multilib autoconf automake libtool flex bison gdb gcc-doc
gcc-10-multilib gcc-10-locales glibc-doc libstdc++-10-doc make-doc ed diffutils-doc
The following NEW packages will be installed:
binutils binutils-common binutils-x86-64-linux-gnu build-essential dctrl-tools dkms dpkg-dev fakeroot g++ g++-10 gcc gcc-10 libalgorithm-diff-perl
libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan6 libatomic1 libbinutils libc-dev-bin libc-devtools libc6-dev libcc1-0 libcrypt-dev
libctf-nobfd0 libctf0 libfakeroot libgcc-10-dev libitm1 liblsan0 libnsl-dev libstdc++-10-dev libtirpc-dev libtsan0 libubsan1
linux-compiler-gcc-10-x86 linux-headers-5.10.0-11-amd64 linux-headers-5.10.0-11-common linux-headers-amd64 linux-kbuild-5.10 linux-libc-dev make
manpages-dev patch
0 upgraded, 43 newly installed, 0 to remove and 0 not upgraded.
Need to get 62.0 MB of archives.
After this operation, 258 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
```
Once this is done we can **insert** the CD.
You can verify the disk's content via the files explorer in gnome.
![CD](../assets/VirtualBox_debian_18_02_2022_15_01_18.png)
Now, open a terminal and run the following.
```
waldek@hellodebian:~$ cd /media/cdrom0/
waldek@hellodebian:/media/cdrom0$ ls
AUTORUN.INF NT3x TRANS.TBL VBoxLinuxAdditions.run VBoxWindowsAdditions.exe
autorun.sh OS2 VBoxDarwinAdditions.pkg VBoxSolarisAdditions.pkg VBoxWindowsAdditions-x86.exe
cert runasroot.sh VBoxDarwinAdditionsUninstall.tool VBoxWindowsAdditions-amd64.exe
waldek@hellodebian:/media/cdrom0$ sudo bash VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 6.1.28 Guest Additions for Linux........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel
modules. This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions: /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions: /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Building the modules for kernel 5.10.0-11-amd64.
update-initramfs: Generating /boot/initrd.img-5.10.0-11-amd64
VirtualBox Guest Additions: Running kernel modules will not be replaced until
the system is restarted
waldek@hellodebian:/media/cdrom0$ sudo reboot now
```
Once the machine is rebooted you'll can resize the window and the screen resolution will adapt automatically!
You can also enable copy/paste and drag and drop between your host and VM now.
![full screen](../assets/VirtualBox_debian_18_02_2022_15_08_01.png)
# Introduction to the command line
We'll be using a few new *words* to reference the command line such as *shell*, *bash* and *terminal* through out the course.
They all pretty much mean the same thing but with some small, and not so important, differences between them.
Essentially a command line is a **textual interface** for humans to operate a computer.
What is very important to understand is that textual commands and graphical actions operate on the **same** computer.
For example, if you create a file via the command line, it will show up in you file explorer and vice versa.
The graphical and textual interfaces are just different *representations* of the same machine.
Now open up a terminal and you'll see the following.
```
waldek@hellodebian:~$
```
This is what we call a [prompt](https://en.wikipedia.org/wiki/Command-line_interface#Command_prompt).
It's not much but it's our *window* into the computer.
As with most things in life you can question it's *who, where, what and when*.
This information is actually **embedded** in the prompt.
Let's break it down.
* `waldek` is **who** I am on this computer
* `hellodebian` is the **what**, as in what computer I'm operating on
* `~` is **where** I am located on this computer
What about the *when* then?
Let's type in `date` and see what happens.
```
waldek@hellodebian:~$ date
Fri 18 Feb 2022 03:46:59 PM CET
waldek@hellodebian:~$
```
There we see our **when**!
But this miniscule operation illustrates us the **fundamental** operation of a command line!
1. we have a prompt where we can run a program
2. the program runs and outputs it's information on the terminal
3. once the program **finishes** we can run an other program
I'm deliberately saying program here but is `date` *really* a program?
It's a bit basic no?
Well, it is a program and most *commands* you'll type into your terminal are actually programs.
We can illustrate this as follows.
```
waldek@hellodebian:~$ vlc
VLC media player 3.0.16 Vetinari (revision 3.0.13-8-g41878ff4f2)
[0000559c46ee95b0] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
[0000559c46f89790] main playlist: playlist is empty
```
Vlc is now running and the terminal is *blocked* meaning we can't run other programs or commands in it.
If you try to run the `date` command again, or `ls` or `htop`, it won't work!
Try it out if you don't believe me.
But what happens if you **close** vlc?
The commands you typed get executed!
This is an illustration of the **sequential** nature of a command line.
Now, I don't think we have sufficiently *proven* that `date` is a full blown program so let's dig a bit deeper.
```
waldek@hellodebian:~$ which vlc
/usr/bin/vlc
waldek@hellodebian:~$ which date
/usr/bin/date
waldek@hellodebian:~$ which which
/usr/bin/which
```
There is quite bit to *unpack* in the example above.
First, what on earth is `which`?
Well, it's *also* a program and it's sole purpose in life is to tell you **where** a program is located on your system.
Because `which` by itself does not make a lot of sense it needs what we call an **argument**.
Here the argument is the name of the program we want to know it's location of.
The existence of arguments is the second big thing we discovered here.
The third new thing we can observe here is what we call **paths**, meaning locations on the system.
For example, `vlc` is a *binary* program located in a **folder** called `bin` which is located in a folder called `usr` which is at the *root* of your system.
If this sounds complicated, don't worry, we'll go into detail a bit later.
Now that we know **where** some of our programs are located, let's find out **what** they are.
The methodology is the same as with `which` but we'll use an other program called `file` who's purpose in life is to tell more about the **content** of a certain file.
Logically, `file` needs an argument and this argument is the **path** to the file you want to inspect.
```
waldek@hellodebian:~$ file /usr/bin/vlc
/usr/bin/vlc: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=51c40f8234213415771b3a344cab25a140543f8a, for GNU/Linux 3.2.0, stripped
waldek@hellodebian:~$ file /usr/bin/date
/usr/bin/date: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b740f054aaef6a85aff024858c914c7eae70a6a5, for GNU/Linux 3.2.0, stripped
waldek@hellodebian:~$ file /usr/bin/which
/usr/bin/which: POSIX shell script, ASCII text executable
waldek@hellodebian:~$ file $(which which) # this is some command line kung fu...
/usr/bin/which: POSIX shell script, ASCII text executable
waldek@hellodebian:~$
```
Here we learn that both `vlc` and `date` are **executables**, compiled for an x86-64 system.
I would say they are both created *equally* no?
Both are actual programs.
But what about `which`?
It's also an executable but not compiled, it's a *POSIX shell script*.
So not all programs *are* created equally?
## Compiled vs interpreted
Executing a file, or program, means you take this file and tell the computer it needs to execute the actions that are stored in the file.
Compiled programs contain actual [instructions](https://en.wikipedia.org/wiki/Instruction_set_architecture#Instructions) the computer understands out of the box.
This means that programs that are compiled are always compiled for a specify architecture which in our case is x86-64.
On a Raspberry Pi this would be armhf or arm64.
Interpreted programs are not compiled to machine code but when we run them each line is passed to an appropriate **interpreter** and executed **line by line**.
The first line of a script is often the path to the interpreter that *understands* the code that will follow.
Popular interpreted languages are `bash`, `sh`, `python`, `php`, ...
We can take it *one* more step forward and peak into the *content* of the files.
A nice little program to do this is called `head` who's purpose in life is to show the first few lines of a file.
First for `vlc`.
```
waldek@hellodebian:~$ head /usr/bin/vlc
ELF>@<40>1@8
HHh,h<h<<3C><><EFBFBD>,<2C><<3C>< <20><><EFBFBD>DDP<44>td###<23><>Q<EFBFBD>tdR<64>tdh,h<h<<3C><>/lib64/ld-linux-x86-64.so.2GNUQ<EFBFBD><EFBFBD>4!4w4L<34>%<25>@T?<3F>GNU)<29>)*<2A>e<EFBFBD>m9<6D>y<EFBFBD><79><EFBFBD><EFBFBD> <20><>)F <20>, X<>`
Pco<EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD><EFBFBD>ZD<EFBFBD>
<20><>/<2F><><EFBFBD>h<EFBFBD>"<22> _ITM_deregisterTMCloneTable__gmon_start___ITM_registerTMCloneTablelibvlc_set_app_idlibvlc_newlibvlc_set_user_agentlibvlc_get_changesetlibvlc_get_versionlibvlc_set_exit_handlerlibvlc_add_intflibvlc_playlist_playlibvlc_releasesigwaitflockfilepthread_killpthread_sigmaskpthread_mutex_lockpthread_mutex_unlockfunlockfilesigactiondlsymdlerrorfflushsignal__stack_chk_failabortisattysigemptysetrand_r__fprintf_chksigaddsetmemcpystderrsigdelsetalarmfwritegeteuid__vfprintf_chk__cxa_finalizepthread_self__libc_start_main__register_atforklibvlc.so.5libpthread.so.0libdl.so.2libc.so.6GLIBC_2<EFBFBD>ri5GLIB<EFBFBD>ti.14GL<EFBFBD>u<EFBFBD>i2.4Glh<EFBFBD>p<EFBFBD>@<40>?<3F>?GLIBC_2.3.G u<>i lW u<>i lb<6C><62>xii
<EFBFBD>?
<20>?<3F>?) @*<2A>><3E>><3E>><3E>><3E>><3E>><3E><>> <09>>
??? ?(?0?8?@?H?P?X?`?<3F>h??x?<3F>?<3F>?<3F>? <20>?!<21>?"<22>?#<23>?$<24>?%<25>?&<26>?'<27>?(H<>H<EFBFBD><48>/H<><48>t<EFBFBD><74>H<EFBFBD><48><EFBFBD>5<EFBFBD>.<2E>%<25>.@<40>%<25>.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%z.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%r.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%j.h<><68><EFBFBD><EFBFBD><EFBFBD>%b.h<><68><EFBFBD><EFBFBD><EFBFBD>%Z.h<><68><EFBFBD><EFBFBD><EFBFBD>%R.h<><68><EFBFBD><EFBFBD><EFBFBD>%J.h<>p<EFBFBD><70><EFBFBD><EFBFBD>%B.<2E>`<60><><EFBFBD><EFBFBD>%:.h <09>P<EFBFBD><50><EFBFBD><EFBFBD>%2.h
<EFBFBD>@<40><><EFBFBD><EFBFBD>%*.h
<20>0<EFBFBD><30><EFBFBD><EFBFBD>%".h
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%.h<><68><EFBFBD><EFBFBD><EFBFBD>% <20> <20><><EFBFBD><EFBFBD>%<25>.h
.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD>%<25>-h<>p<EFBFBD><70><EFBFBD><EFBFBD>%<25>-h<>`<60><><EFBFBD><EFBFBD>%<25>-h<>P<EFBFBD><50><EFBFBD><EFBFBD>%<25>-h<><68>@<40><><EFBFBD><EFBFBD>%<25>-h0<68><30><EFBFBD><EFBFBD>%<25>-h<> <20><><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD>%<25>-h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>L<EFBFBD><4C>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>S<EFBFBD>[Hc<48>H<EFBFBD>G<EFBFBD><47><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>:<3A><><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>-<2D><><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD> <20><><EFBFBD><EFBFBD>
L<><4C>
H<><48>H<EFBFBD>5<EFBFBD>
fHn<48>H<EFBFBD>BfHn<48>H<EFBFBD><48> H<><48><EFBFBD>fl<66>I<EFBFBD>H)<29>L<EFBFBD>t$L<><4C>I<EFBFBD><49><EFBFBD>H<EFBFBD><48>L<EFBFBD><4C><EFBFBD>I<EFBFBD>~<7E>o<EFBFBD><6F><EFBFBD>Lc<4C>K<EFBFBD><4B><EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD><49>H<EFBFBD><48><EFBFBD><EFBFBD>H<EFBFBD><48>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD>5<EFBFBD><35>S<EFBFBD><53><EFBFBD>H<EFBFBD>
H<EFBFBD>/
L<><4C>H<EFBFBD>5
<20>v<EFBFBD><76><EFBFBD>H<EFBFBD>
H<>5
L<><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD>5!
L<><4C><EFBFBD>!<21><><EFBFBD>H<EFBFBD>5
L<EFBFBD><EFBFBD><EFBFBD>'<27><><EFBFBD>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>H<EFBFBD><48><EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>S<EFBFBD><53><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD>5<EFBFBD><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>5<EFBFBD><35><EFBFBD><EFBFBD>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD><49><EFBFBD>&<26><><EFBFBD>H<EFBFBD>=<3D>*M<><4D>H<EFBFBD><48><EFBFBD>@<40><><EFBFBD>u
H<><48><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD>A<EFBFBD>H<EFBFBD>E<EFBFBD>dH+%(u?H<>e<EFBFBD>D<EFBFBD><44>[A\A]A^]<5D>I<EFBFBD>M<EFBFBD>H<EFBFBD>=\*H<><48>
CH<EFBFBD>=L<><4C><EFBFBD><EFBFBD><EFBFBD>)<29>DH<44>=<3D>)H<><48>)H9<48>tH<74><48>)H<><48>t<EFBFBD>f.<2E>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD>=<3D>)H<>5<EFBFBD>)H)<29>H<EFBFBD><48>H<EFBFBD><48>?H<><48>H<EFBFBD>H<EFBFBD><48>tH<74>U)H<><48><EFBFBD><EFBFBD>fD<66><44><EFBFBD>=q)u/UH<55>=6)H<><48>t
H<>=:)<29><><EFBFBD><EFBFBD><EFBFBD>h<EFBFBD><68><EFBFBD><EFBFBD>I)]<5D><><EFBFBD><EFBFBD><EFBFBD>{<7B><><EFBFBD>f.<2E><>1<EFBFBD><31><EFBFBD>$<24><><EFBFBD>@H<>?<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><>AUI<55><49>ATI<54><49>UH<55><48>SH<53><48>H<EFBFBD><48><EFBFBD>L<EFBFBD>D$@L<>L$H<><48>t7)D$P)L$`)T$p)<29>$<24>)<29>$<24>)<29>$<24>)<29>$<24>)<29>$<24>dH<64>%(H<>D$1<>H<EFBFBD>={(H<>T$ H<><48>$<24>$ <20>D$0H<30>DH<44>T$<24><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><>v1H<31>=B(<28><><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD>D$dH+%(uH<75><48><EFBFBD>[]A\A]<5D><><EFBFBD><EFBFBD>H<EFBFBD>=(I<><49>1<EFBFBD><31>
H<EFBFBD><EFBFBD>H<EFBFBD>=7 H<>5H<35>=?'<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD>#<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<EFBFBD>ATI<54><49><EFBFBD>f<EFBFBD><66><EFBFBD>H<EFBFBD>=<3D>'L<><4C>H<EFBFBD>I<EFBFBD><49><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD>i<EFBFBD><69><EFBFBD>1<EFBFBD>1<EFBFBD><31>.(<28>f<EFBFBD><66>=(UH<55><48>u#H<>5H<35><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD><48>t5H<35><48>]<5D><>DI<44><49>1<EFBFBD>H<EFBFBD>
<EFBFBD>H<EFBFBD>H<EFBFBD>5<EFBFBD>H<EFBFBD>=7&<26><>&<26><><EFBFBD><EFBFBD>X1<58>Z]A\A]<5D>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD>ff.<2E><><EFBFBD>='UH<55><48>u#H<>5<EFBFBD>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD><48>t5H<35><48>]<5D><>DI<44><49>1<EFBFBD>H<EFBFBD><48>RH<52>
!"<22><><EFBFBD><EFBFBD>H<EFBFBD>H<EFBFBD><48>DESKTOP_STARTUP_ID--no-ignore-config--media-library--dbusvlcorg.VideoLAN.VLCVLC/3.0.16VLC media playerglobalhotkeys,noneVLC is not supposed to be run as root. Sorry.
If you need to use real-time priorities and/or privileged TCP ports
you can use %s-wrapper (make sure it is Set-UID root and
```
And now of `which`.
```
waldek@hellodebian:~$ head /usr/bin/which
#! /bin/sh
set -ef
if test -n "$KSH_VERSION"; then
puts() {
print -r -- "$*"
}
else
puts() {
printf '%s\n' "$*"
waldek@hellodebian:~$
```
Notice how the `vlc` file is mostly **not human readable** but we can still make out some keywords?
The `which` file however is perfectly readable!
The first line of the `which` file is `#! /bin/sh` which is the path to the interpreter.
The `#!` is called a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)).
We can dig into this to learn more about this mysterious `sh`.
```
waldek@hellodebian:~$ file /bin/sh
/bin/sh: symbolic link to dash
waldek@hellodebian:~$ which dash
/usr/bin/dash
waldek@hellodebian:~$ file /usr/bin/dash
/usr/bin/dash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=cb6911fd56559717336c938bef1ce479b0a85b35, for GNU/Linux 3.2.0, stripped
waldek@hellodebian:~$
```
Surprise surprise!
The *interpreter* is a compiled program!
When you think about it it does make sense because at the end of the day the computer *only* understands machine instructions.
So when you execute a script each line of code is converted to machine instructions on the spot.
This makes scripts easier to write but slower at execution.
## Note on file extensions
Linux does not rely as much on file extensions as windows does.
We could even say it often does not care about them.
Due to the decentralized nature of Linux development, some programs *do* care about them while others don't.
It's a bit of hit and miss but I advise you to read [this](https://askubuntu.com/questions/803434/do-file-extensions-have-any-purpose-in-linux) post on AskUbuntu for a more detailed explanation.
# More about paths
The prompt in our terminal tells us who we are, on which machine, and **where** we are located.
This where is symbolized with the `~` character.
But where is this where?
```
waldek@hellodebian:~$ pwd
/home/waldek
waldek@hellodebian:~$
```
The `pwd` program **p**rints our **w**orking **d**irectory, meaning where we are located on our system.
A user's home directory is symbolized with this tilde character.
We can move around our system with the `cd` command which is an abbreviation of **c**hange **d**irectory.
`cd` by itself seems to to *nothing* but this is not the case.
It's a *shortcut* to go to your user's home directory.
Let's try this out.
```
waldek@hellodebian:~$ cd
waldek@hellodebian:~$ cd /usr/bin
waldek@hellodebian:/usr/bin$ cd
waldek@hellodebian:~$ cd -
/usr/bin
waldek@hellodebian:/usr/bin$ cd
waldek@hellodebian:~$
```
The first line appears to do nothing because we are already in our home directory.
Next we move to the directory which contains the programs we discovered before and we see our prompt change.
It now shows *where* we are located!
The next line takes us back to our home and from there we can move *back to where we were before* with the `cd -` command.
This last command is also a handy *shortcut*!
Moving around is nice but once we arrive at our destination it would be practical to be able to list the files in that directory no?
This can be done with the `ls` program.
For example.
```
waldek@hellodebian:~$ cd /usr/bin/
waldek@hellodebian:/usr/bin$ ls
'[' getconf nmtui-hostname systemd-escape
7z getent nohup systemd-hwdb
7za getfacl notify-send systemd-id128
7zr getkeycodes nproc systemd-inhibit
aa-enabled getopt nroff systemd-machine-id-setup
aa-exec gettext nsenter systemd-mount
aconnect gettext.sh nslookup systemd-notify
add-apt-repository gio nstat systemd-path
addpart gio-querymodules nsupdate systemd-resolve
addr2line gjs ntfs-3g systemd-run
alsabat gjs-console ntfs-3g.probe systemd-socket-activate
alsaloop gkbd-keyboard-display ntfscat systemd-stdio-bridge
alsamixer glib-compile-schemas ntfscluster systemd-sysusers
alsatplg gmake ntfscmp systemd-tmpfiles
alsaucm gnome-calculator ntfsdecrypt systemd-tty-ask-password-agent
# ------------------------------------
# --- cropped the list for clarity ---
# ------------------------------------
gdk-pixbuf-csource nisdomainname system-config-printer-applet zforce
gdk-pixbuf-pixdata nl systemctl zgrep
gdk-pixbuf-thumbnailer nm systemd zipdetails
gdm-control nm-applet systemd-analyze zipgrep
gdmflexiserver nmcli systemd-ask-password zipinfo
gdm-screenshot nm-connection-editor systemd-cat zless
gedit nm-online systemd-cgls zmore
gencat nmtui systemd-cgtop znew
geqn nmtui-connect systemd-delta
GET nmtui-edit systemd-detect-virt
waldek@hellodebian:/usr/bin$
```
That's a **lot** of programs!
Can you find `cd` in there?
Spoiler alert, you wont...
Maybe it's located somewhere else?
Let's have a look.
```
waldek@hellodebian:/usr/bin$ which cd
waldek@hellodebian:/usr/bin$
```
`cd` is not a program but a builtin command.
From a practical point of view there is no difference but I do like to mention it for completeness.
Later down the line it will help you to contextualize the differences between shells a bit better.
But built into *what*?
Below you can see a snippet of a part of the `bash-builtin` manual.
For now just accept the specific shell we're using is called `bash`.
```
BASH-BUILTINS(7) Miscellaneous Information Manual BASH-BUILTINS(7)
NAME
bash-builtins - bash built-in commands, see bash(1)
SYNOPSIS
bash defines the following built-in commands: :, ., [, alias, bg, bind, break, builtin, case, cd, command, compgen, complete, continue, de
clare, dirs, disown, echo, enable, eval, exec, exit, export, fc, fg, getopts, hash, help, history, if, jobs, kill, let, local, logout, popd,
printf, pushd, pwd, read, readonly, return, set, shift, shopt, source, suspend, test, times, trap, type, typeset, ulimit, umask, unalias,
unset, until, wait, while.
```
## Absolute and relative paths
> All roads lead to Rome.
There are multiple ways to go to the same location on your system.
You can always go either in an **absolute** way, or in *multiple* **relative** ways.
The root of your system is `/` and to list what we can find there we can use `ls`.
```
waldek@hellodebian:~$ cd /
waldek@hellodebian:/$ ls
bin dev home initrd.img.old lib32 libx32 media opt root sbin sys usr vmlinuz
boot etc initrd.img lib lib64 lost+found mnt proc run srv tmp var vmlinuz.old
waldek@hellodebian:/$
```
From here we can go back home in multiple ways.
```
waldek@hellodebian:/$ cd
waldek@hellodebian:~$ cd -
/
waldek@hellodebian:/$ cd home/waldek/
waldek@hellodebian:~$ cd -
/
waldek@hellodebian:/$ cd /home/waldek/
waldek@hellodebian:~$
```
The first one is the handy shortcut we learned, and we go back to the root of our system with the `cd -` shortcut.
The following two manipulations look very similar but there is a subtle difference.
The first one `home/waldek` is a **relative** path, and the second one `/home/waldek` is an **absolute** one.
Relative paths depend on where you are located, absolute ones always point to the same location.
An example.
```
waldek@hellodebian:~$ cd /usr/bin/
waldek@hellodebian:/usr/bin$ cd /home/waldek/
waldek@hellodebian:~$ cd -
/usr/bin
waldek@hellodebian:/usr/bin$ cd home/waldek
-bash: cd: home/waldek: No such file or directory
waldek@hellodebian:/usr/bin$
```
The second command fails because from where I'm standing, there is no folder called `home/waldek`!
I can however still go to my home in a relative way but I need to *go back* a few directories first.
```
waldek@hellodebian:/usr/bin$ cd ../../home/waldek/
waldek@hellodebian:~$ pwd
/home/waldek
waldek@hellodebian:~$
```
The `..` means go **back** one directory so in our example we go back **two** directories, which brings us to the `/` of our system and from there we go **up** to `home` and then `waldek`.
## `root` and `/` and `/root` are not the same thing
The word *root* has multiple meanings and can be a bit confusing at the start.
Every Linux machine will have a `root` user **and** a `/` of the system.
The `root` user is an account essential to the proper working of a Linux system, whereas `/` is a location, the *root* of the filesystem.
The `/root` is also a location but is the **home** of the user `root`, located at the `/` of the filesystem.
If this sounds confusing read the above paragraph slowly until you see the differences.
I do want to note that the name of the user `root` *can* change but it's ID will always be `0`.
We'll go into detail about users and ID's later down the line.
# Exercise
Explore your system a bit using `cd` and `ls`.
You'll probably encounter some weird messages along the way.
Keep note of them so we can discuss it together.
# A pit stop to review what we've learned so far
Below is a list of programs and command we've seen so far.
We've seen that some take arguments, some don't.
This list will grow as we go so I advise you to take some notes of your own.
|command|description|
|---|---|
|systemctl|manipulate running services|
|apt|the Debian package manager|
|htop|a command line task manager we installed|
|vlc|a video player we installed|
|date|display the time of day|
|which|show the path to an executable|
|file|print more information about a file's content|
|head|show the first lines of a file|
|pwd|print working directory|
|cd|change directory|
|ls|list content of a directory|
# Arguments and flags
The `ls` program is one of the most used commands.
It's like a very basic *file explorer* in a graphical environment and just like it's graphical counter part you can use it to display it's data in different ways.
Think of the *details* versus *thumbnail* views in your favorite explorer.
But how do you do this?
We can **add flags or options** to the program to modify it's behavior.
Have a look at the output below.
```
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
waldek@hellodebian:~$ ls -l
total 32
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Desktop
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Documents
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Downloads
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Music
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Pictures
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Public
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Templates
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Videos
waldek@hellodebian:~$ ls -a
. .bashrc Desktop .gnupg .profile Templates .vboxclient-seamless.pid
.. .cache .dmrc .local Public .vboxclient-clipboard.pid Videos
.bash_history .config Documents Music .python_history .vboxclient-display-svga-x11.pid .Xauthority
.bash_logout .dbus Downloads Pictures .ssh .vboxclient-draganddrop.pid .xsession-errors
```
The `-l` and `-a` additions are what we call *flags* or *options*.
Aren't they just extra *arguments*?
There is no real rule to the naming of this concept but [this](https://unix.stackexchange.com/questions/285575/whats-the-difference-between-a-flag-an-option-and-an-argument) is a rather interesting take.
We can combine arguments if we want, and some programs even allow *concatenation* of arguments.
Have a look below to understand what I mean by that.
```
waldek@hellodebian:~$ ls -a -l
total 112
drwxr-xr-x 16 waldek waldek 4096 Feb 21 18:12 .
drwxr-xr-x 3 root root 4096 Feb 18 12:49 ..
-rw------- 1 waldek waldek 2772 Feb 22 10:45 .bash_history
-rw-r--r-- 1 waldek waldek 220 Feb 18 12:49 .bash_logout
-rw-r--r-- 1 waldek waldek 3526 Feb 18 12:49 .bashrc
drwx------ 16 waldek waldek 4096 Feb 18 14:24 .cache
drwx------ 20 waldek waldek 4096 Feb 18 14:23 .config
drwx------ 3 waldek waldek 4096 Feb 18 12:52 .dbus
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Desktop
-rw-r--r-- 1 waldek waldek 35 Feb 18 13:33 .dmrc
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Documents
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Downloads
drwx------ 2 waldek waldek 4096 Feb 18 15:07 .gnupg
drwxr-xr-x 3 waldek waldek 4096 Feb 18 12:50 .local
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Music
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Pictures
-rw-r--r-- 1 waldek waldek 807 Feb 18 12:49 .profile
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Public
-rw------- 1 waldek waldek 11 Feb 21 18:12 .python_history
drwx------ 2 waldek waldek 4096 Feb 21 12:45 .ssh
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Templates
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-clipboard.pid
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-display-svga-x11.pid
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-draganddrop.pid
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-seamless.pid
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Videos
-rw------- 1 waldek waldek 56 Feb 18 13:33 .Xauthority
-rw------- 1 waldek waldek 2701 Feb 18 13:33 .xsession-errors
waldek@hellodebian:~$ ls -la
total 112
drwxr-xr-x 16 waldek waldek 4096 Feb 21 18:12 .
drwxr-xr-x 3 root root 4096 Feb 18 12:49 ..
-rw------- 1 waldek waldek 2772 Feb 22 10:45 .bash_history
-rw-r--r-- 1 waldek waldek 220 Feb 18 12:49 .bash_logout
-rw-r--r-- 1 waldek waldek 3526 Feb 18 12:49 .bashrc
drwx------ 16 waldek waldek 4096 Feb 18 14:24 .cache
drwx------ 20 waldek waldek 4096 Feb 18 14:23 .config
drwx------ 3 waldek waldek 4096 Feb 18 12:52 .dbus
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Desktop
-rw-r--r-- 1 waldek waldek 35 Feb 18 13:33 .dmrc
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Documents
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Downloads
drwx------ 2 waldek waldek 4096 Feb 18 15:07 .gnupg
drwxr-xr-x 3 waldek waldek 4096 Feb 18 12:50 .local
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Music
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Pictures
-rw-r--r-- 1 waldek waldek 807 Feb 18 12:49 .profile
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Public
-rw------- 1 waldek waldek 11 Feb 21 18:12 .python_history
drwx------ 2 waldek waldek 4096 Feb 21 12:45 .ssh
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Templates
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-clipboard.pid
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-display-svga-x11.pid
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-draganddrop.pid
-rw-r----- 1 waldek waldek 5 Feb 18 15:06 .vboxclient-seamless.pid
drwxr-xr-x 2 waldek waldek 4096 Feb 18 12:50 Videos
-rw------- 1 waldek waldek 56 Feb 18 13:33 .Xauthority
-rw------- 1 waldek waldek 2701 Feb 18 13:33 .xsession-errors
waldek@hellodebian:~$
```
# Getting help
## Options
OK, so we have *a lot* of programs we can use on the command line, plus we can change how they work by adding obscure characters.
How on earth can we *discover* what a program can and can't do?
Introducing the **most important flag**: `--help`.
Most programs come with builtin help to explain you how to use the program.
Often, but not always, this help can be displayed on the terminal by adding the `--help` flag.
Let's investigate this.
```
waldek@hellodebian:~$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
Mandatory arguments to long options are mandatory for short options too.
-a, --all do not ignore entries starting with .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
-b, --escape print C-style escapes for nongraphic characters
--block-size=SIZE with -l, scale sizes by SIZE when printing them;
e.g., '--block-size=M'; see SIZE format below
-B, --ignore-backups do not list implied entries ending with ~
-c with -lt: sort by, and show, ctime (time of last
modification of file status information);
with -l: show ctime and sort by name;
otherwise: sort by ctime, newest first
-C list entries by columns
--color[=WHEN] colorize the output; WHEN can be 'always' (default
if omitted), 'auto', or 'never'; more info below
-d, --directory list directories themselves, not their contents
-D, --dired generate output designed for Emacs' dired mode
-f do not sort, enable -aU, disable -ls --color
-F, --classify append indicator (one of */=>@|) to entries
--file-type likewise, except do not append '*'
--format=WORD across -x, commas -m, horizontal -x, long -l,
single-column -1, verbose -l, vertical -C
--full-time like -l --time-style=full-iso
-g like -l, but do not list owner
--group-directories-first
group directories before files;
can be augmented with a --sort option, but any
use of --sort=none (-U) disables grouping
-G, --no-group in a long listing, don't print group names
-h, --human-readable with -l and -s, print sizes like 1K 234M 2G etc.
--si likewise, but use powers of 1000 not 1024
-H, --dereference-command-line
follow symbolic links listed on the command line
--dereference-command-line-symlink-to-dir
follow each command line symbolic link
that points to a directory
--hide=PATTERN do not list implied entries matching shell PATTERN
(overridden by -a or -A)
--hyperlink[=WHEN] hyperlink file names; WHEN can be 'always'
(default if omitted), 'auto', or 'never'
--indicator-style=WORD append indicator with style WORD to entry names:
none (default), slash (-p),
file-type (--file-type), classify (-F)
-i, --inode print the index number of each file
-I, --ignore=PATTERN do not list implied entries matching shell PATTERN
-k, --kibibytes default to 1024-byte blocks for disk usage;
used only with -s and per directory totals
-l use a long listing format
-L, --dereference when showing file information for a symbolic
link, show information for the file the link
references rather than for the link itself
-m fill width with a comma separated list of entries
-n, --numeric-uid-gid like -l, but list numeric user and group IDs
-N, --literal print entry names without quoting
-o like -l, but do not list group information
-p, --indicator-style=slash
append / indicator to directories
-q, --hide-control-chars print ? instead of nongraphic characters
--show-control-chars show nongraphic characters as-is (the default,
unless program is 'ls' and output is a terminal)
-Q, --quote-name enclose entry names in double quotes
--quoting-style=WORD use quoting style WORD for entry names:
literal, locale, shell, shell-always,
shell-escape, shell-escape-always, c, escape
(overrides QUOTING_STYLE environment variable)
-r, --reverse reverse order while sorting
-R, --recursive list subdirectories recursively
-s, --size print the allocated size of each file, in blocks
-S sort by file size, largest first
--sort=WORD sort by WORD instead of name: none (-U), size (-S),
time (-t), version (-v), extension (-X)
--time=WORD change the default of using modification times;
access time (-u): atime, access, use;
change time (-c): ctime, status;
birth time: birth, creation;
with -l, WORD determines which time to show;
with --sort=time, sort by WORD (newest first)
--time-style=TIME_STYLE time/date format with -l; see TIME_STYLE below
-t sort by time, newest first; see --time
-T, --tabsize=COLS assume tab stops at each COLS instead of 8
-u with -lt: sort by, and show, access time;
with -l: show access time and sort by name;
otherwise: sort by access time, newest first
-U do not sort; list entries in directory order
-v natural sort of (version) numbers within text
-w, --width=COLS set output width to COLS. 0 means no limit
-x list entries by lines instead of by columns
-X sort alphabetically by entry extension
-Z, --context print any security context of each file
-1 list one file per line. Avoid '\n' with -q or -b
--help display this help and exit
--version output version information and exit
The SIZE argument is an integer and optional unit (example: 10K is 10*1024).
Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).
Binary prefixes can be used, too: KiB=K, MiB=M, and so on.
The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.
FORMAT is interpreted like in date(1). If FORMAT is FORMAT1<newline>FORMAT2,
then FORMAT1 applies to non-recent files and FORMAT2 to recent files.
TIME_STYLE prefixed with 'posix-' takes effect only outside the POSIX locale.
Also the TIME_STYLE environment variable sets the default style to use.
Using color to distinguish file types is disabled both by default and
with --color=never. With --color=auto, ls emits color codes only when
standard output is connected to a terminal. The LS_COLORS environment
variable can change the settings. Use the dircolors command to set it.
Exit status:
0 if OK,
1 if minor problems (e.g., cannot access subdirectory),
2 if serious trouble (e.g., cannot access command-line argument).
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation <https://www.gnu.org/software/coreutils/ls>
or available locally via: info '(coreutils) ls invocation'
waldek@hellodebian:~$
```
The output above teaches us that the options `-la` change the output so it becomes:
* `-a, --all do not ignore entries starting with .`
* `-l use a long listing format`
To *not ignore entries starting with .* we can use two different flags, `-a` or `--all`.
The former is called short arguments and the latter long ones.
The long ones are more *verbose* so it's often easier to understand what a line *does* just by reading it.
Note that `ls` only has one way of showing the help by adding `--help` whereas the help for `htop` can be shown with both `-h` or `--help`.
This inconsistency is sadly a byproduct of the decentralized nature of Linux.
To add to this mess some programs use *single dash long form* (`-help`) but those programs are rather rare.
## Manuals
The `--help` flag is tremendously useful as it gives you an overview of how you can modify a programs behaviour, kind of like settings, but it doesn't always explain you what a program is *for*.
The is where the manuals come into play.
I see the `--help` flag as a *cheat sheet* to quickly discover options and the man pages as a reference.
We can read the manual by calling the `man` program with an argument.
This argument is the *name* of the program you want to read the manual for.
Same idea as with `which`.
```
waldek@hellodebian:~$ man ls
```
You're now in a program called `less`, which is a [pager](https://en.wikipedia.org/wiki/Terminal_pager).
You can scroll the manual with the arrows of `vi` based navigation (which we'll get into later).
If you hit `h` you'll see the builtin documentation of `less` and press `q` to quit (twice if you're in the help section).
This brings you back to your prompt.
It's worth reading the [wikipedia entry](https://en.wikipedia.org/wiki/Man_page) of the `man` command to understand it's history and operation.
The output below illustrates the *tree* of a terminal that's reading a manual.
In a `bash` shell you invoke `man ls` which in turn runs the `pager` program to display the content.
If you're intrigued by this `pstree` program go and read the manual!
```
waldek@hellodebian:~$ pstree 10845 -a
bash
└─man ls
└─pager
waldek@hellodebian:~$
```
Not every command has a manual.
For example, `cd` does not have one.
This is kind of logical because `cd` is a builtin.
To learn more about builtin commands you can use the `help` program.
On it's own it gives you all the builtin command you can invoke and with an argument it outputs the help about that specific command.
```
waldek@hellodebian:~$ help
GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
These shell commands are defined internally. Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
job_spec [&] history [-c] [-d offset] [n] or history -anrw [filename] or history -ps>
(( expression )) if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else>
. filename [arguments] jobs [-lnprs] [jobspec ...] or jobs -x command [args]
: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [>
[ arg... ] let arg [arg ...]
[[ expression ]] local [option] name[=value] ...
alias [-p] [name[=value] ... ] logout [n]
bg [job_spec ...] mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C c>
bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyse> popd [-n] [+N | -N]
break [n] printf [-v var] format [arguments]
builtin [shell-builtin [arg ...]] pushd [-n] [+N | -N | dir]
caller [expr] pwd [-LP]
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p>
cd [-L|[-P [-e]] [-@]] [dir] readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C>
command [-pVv] command [arg ...] readonly [-aAf] [name[=value] ...] or readonly -p
compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlis> return [n]
complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpa> select NAME [in WORDS ... ;] do COMMANDS; done
compopt [-o|+o option] [-DEI] [name ...] set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
continue [n] shift [n]
coproc [NAME] command [redirections] shopt [-pqsu] [-o] [optname ...]
declare [-aAfFgiIlnrtux] [-p] [name[=value] ...] source filename [arguments]
dirs [-clpv] [+N] [-N] suspend [-f]
disown [-h] [-ar] [jobspec ... | pid ...] test [expr]
echo [-neE] [arg ...] time [-p] pipeline
enable [-a] [-dnps] [-f filename] [name ...] times
eval [arg ...] trap [-lp] [[arg] signal_spec ...]
exec [-cl] [-a name] [command [argument ...]] [redirection ...] true
exit [n] type [-afptP] name [name ...]
export [-fn] [name[=value] ...] or export -p typeset [-aAfFgiIlnrtux] [-p] name[=value] ...
false ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]
fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command] umask [-p] [-S] [mode]
fg [job_spec] unalias [-a] name [name ...]
for NAME [in WORDS ... ] ; do COMMANDS; done unset [-f] [-v] [-n] [name ...]
for (( exp1; exp2; exp3 )); do COMMANDS; done until COMMANDS; do COMMANDS; done
function name { COMMANDS ; } or name () { COMMANDS ; } variables - Names and meanings of some shell variables
getopts optstring name [arg ...] wait [-fn] [-p var] [id ...]
hash [-lr] [-p pathname] [-dt] [name ...] while COMMANDS; do COMMANDS; done
help [-dms] [pattern ...] { COMMANDS ; }
waldek@hellodebian:~$ help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
Change the current directory to DIR. The default DIR is the value of the
HOME shell variable.
The variable CDPATH defines the search path for the directory containing
DIR. Alternative directory names in CDPATH are separated by a colon (:).
A null directory name is the same as the current directory. If DIR begins
with a slash (/), then CDPATH is not used.
If the directory is not found, and the shell option `cdable_vars' is set,
the word is assumed to be a variable name. If that variable has a value,
its value is used for DIR.
Options:
-L force symbolic links to be followed: resolve symbolic
links in DIR after processing instances of `..'
-P use the physical directory structure without following
symbolic links: resolve symbolic links in DIR before
processing instances of `..'
-e if the -P option is supplied, and the current working
directory cannot be determined successfully, exit with
a non-zero status
-@ on systems that support it, present a file with extended
attributes as a directory containing the file attributes
The default is to follow symbolic links, as if `-L' were specified.
`..' is processed by removing the immediately previous pathname component
back to a slash or the beginning of DIR.
Exit Status:
Returns 0 if the directory is changed, and if $PWD is set successfully when
-P is used; non-zero otherwise.
waldek@hellodebian:~$
```
Last but not least there are a few extra programs to give you quick and condensed information about a program, `whatis` and `apropos`.
```
waldek@hellodebian:~$ whatis bash
bash (1) - GNU Bourne-Again SHell
waldek@hellodebian:~$ apropos bash
bash (1) - GNU Bourne-Again SHell
bash-builtins (7) - bash built-in commands, see bash(1)
bashbug (1) - report a bug in bash
builtins (7) - bash built-in commands, see bash(1)
dh_bash-completion (1) - install bash completions for package
rbash (1) - restricted bash, see bash(1)
waldek@hellodebian:~$
```
# Exercise
**Read** some manual pages on the commands we've seen until now.
**Apply** some options you read about in the manual to experiment with said programs.
# Creating, modifying and deleting
We've seen how to navigate our filesystem and how to list files and directories at certain locations.
Now let's learn how to add, modify and remove files and directories.
## Directories
The main tool to create directories is `mkdir`.
It's usage is pretty simple, it will create a directory at the location you specify as argument.
This location can be absolute or relative.
By default it will **not** create parent directories if needed but we can force it to do so with the `-p` flag.
```
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
waldek@hellodebian:~$ mkdir website
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos website
waldek@hellodebian:~$ ls website/
waldek@hellodebian:~$ mkdir website/page_one/assets
mkdir: cannot create directory website/page_one/assets: No such file or directory
waldek@hellodebian:~$ mkdir -p website/page_one/assets
waldek@hellodebian:~$ ls -R website/
website/:
page_one
website/page_one:
assets
website/page_one/assets:
waldek@hellodebian:~$
```
The counterpart to `mkdir` is `rmdir` which can be used to remove **empty** directories.
As it can only remove empty directories it's not used that much but it's worth knowing it exists.
```
waldek@hellodebian:~$ rmdir website/
rmdir: failed to remove 'website/': Directory not empty
waldek@hellodebian:~$ rmdir website/page_one/
rmdir: failed to remove 'website/page_one/': Directory not empty
waldek@hellodebian:~$ rmdir website/page_one/assets/
waldek@hellodebian:~$ rmdir website/page_one/
waldek@hellodebian:~$ rmdir website/
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
waldek@hellodebian:~$
```
To remove directories that have subdirectories or files in them we need to use an other program, `rm` but with a specific flag `-r`.
It works as such.
```
waldek@hellodebian:~$ mkdir -p website/page_one/assets
waldek@hellodebian:~$ rm website/
rm: cannot remove 'website/': Is a directory
waldek@hellodebian:~$ rm -r website/
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
waldek@hellodebian:~$
```
**There is no trash or recycle bin on the command line! Removed is removed so think before you hit enter.**
## Files
We can create empty files with the `touch` command.
It's worth pointing out that using `touch` to create files is not it's main purpose.
Reading the manual the fact that it creates files is kind of an extra feature.
Non the less, it's widely used to create files.
```
TOUCH(1) User Commands TOUCH(1)
NAME
touch - change file timestamps
SYNOPSIS
touch [OPTION]... FILE...
DESCRIPTION
Update the access and modification times of each FILE to the current time.
A FILE argument that does not exist is created empty, unless -c or -h is supplied.
A FILE argument string of - is handled specially and causes touch to change the times of the file associated with standard output.
Mandatory arguments to long options are mandatory for short options too.
```
In practice it works as follows.
We can create files with `touch` and delete them with `rm`.
For deleting files we don't need any extra flags as opposed to directories.
```
waldek@hellodebian:~$ mkdir -p website/page_one/assets
waldek@hellodebian:~$ ls website/
page_one
waldek@hellodebian:~$ touch website/index.html
waldek@hellodebian:~$ ls website/
index.html page_one
waldek@hellodebian:~$ file website/index.html
website/index.html: empty
waldek@hellodebian:~$ rm website/index.html
waldek@hellodebian:~$ ls website/
page_one
waldek@hellodebian:~$ file website/index.html
website/index.html: cannot open `website/index.html' (No such file or directory)
waldek@hellodebian:~$
```
What if you created the file in the wrong place?
With `mv` we can move files from one location to an other.
When you think about it, renaming is actually the *same* as moving so there is no specific program to rename files or folders.
```
waldek@hellodebian:~$ touch index.html
waldek@hellodebian:~$ ls
Desktop Documents Downloads index.html Music Pictures Public Templates Videos website
waldek@hellodebian:~$ mv index.html website/indexxxx.html
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos website
waldek@hellodebian:~$ ls website/
indexxxx.html page_one
waldek@hellodebian:~$ mv website/indexxxx.html website/index.html
waldek@hellodebian:~$ ls website/
index.html page_one
waldek@hellodebian:~$
```
We can also move entire directories from one location to another.
```
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos website
waldek@hellodebian:~$ mv website/ Documents/
waldek@hellodebian:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
waldek@hellodebian:~$ ls -R Documents/
Documents/:
website
Documents/website:
index.html page_one
Documents/website/page_one:
assets
Documents/website/page_one/assets:
waldek@hellodebian:~$
```
Copying is done with `cp` and behaves very similar to `mv`.
For example.
```
waldek@hellodebian:~/Documents$ ls
website
waldek@hellodebian:~/Documents$ mv website/ website_1
waldek@hellodebian:~/Documents$ ls
website_1
waldek@hellodebian:~/Documents$ cp website_1/ website_2
cp: -r not specified; omitting directory 'website_1/'
waldek@hellodebian:~/Documents$ cp -r website_1/ website_2
waldek@hellodebian:~/Documents$ ls
website_1 website_2
waldek@hellodebian:~/Documents$ ls -R
.:
website_1 website_2
./website_1:
index.html page_one
./website_1/page_one:
assets
./website_1/page_one/assets:
./website_2:
index.html page_one
./website_2/page_one:
assets
./website_2/page_one/assets:
waldek@hellodebian:~/Documents$
```
### `nano`
### `vi` and `vim`
# Exercise
The only way to learn `vim` is to *use* it.
Luckily `vim-nox` comes with a dedicated *program* to learn it called `vimtutor`.
It's actually a text file that you open up in `vim` where you just need to **read** and **execute** what you've read.
Enjoy!
# Finding stuff
## Finding files
## Searching inside files
## Wildcards and regular expressions
# Exercise
TODO find some specific files and some specific pattern in config files
* [exercise from Linux long](https://gitea.86thumbs.net/waldek/linux_course_doc/src/branch/master/modules/qualifying/learning_regex.md)
# Pipes and redirects
# Users
## Adding and removing users
## Switching user
# Permissions
## Octal number system
## Changing permissions
## Changing ownership
# Remote control of a server
## History
## SSH and SFTP
# Bandit