1
0
Fork 0
mirror of https://codeberg.org/Mo8it/How_To_Linux.git synced 2024-12-05 01:40:32 +00:00

Compare commits

...

15 commits

Author SHA1 Message Date
598311b186 Add coming soon 2022-09-26 21:45:47 +02:00
2cf045440d Add else block 2022-09-26 21:11:21 +02:00
afebcbabc1 Add if block 2022-09-26 20:56:41 +02:00
08c686d8cf Explain comments and read 2022-09-26 20:27:53 +02:00
2c435c1713 Fix typos 2022-09-26 20:14:48 +02:00
58765bc5cf Explain variables 2022-09-26 19:43:10 +02:00
193eb13d05 Explain redirection to stderr and shebang 2022-09-26 18:48:02 +02:00
0f0578ca26 Improve and plan rest of content of day 2 2022-09-23 19:48:13 +02:00
d92f748fe7 Improve last task in day 1 2022-09-23 19:47:41 +02:00
73fe408b4f Fix a typo 2022-09-23 18:51:42 +02:00
ef23a63157 Small changes to tasks of day 1 2022-09-23 18:51:29 +02:00
b9f5bd6d65 Small changes to day 1 2022-09-23 18:42:56 +02:00
f89fd1afeb Update dprint plugin 2022-09-23 13:10:28 +02:00
dc0827abb7 Remove newer clipboard version 2022-09-23 13:10:18 +02:00
13032ca94f Remove note about giving up 2022-09-23 13:10:03 +02:00
11 changed files with 409 additions and 115 deletions

View file

@ -4,6 +4,6 @@
"includes": ["**/*.{md}"],
"excludes": [],
"plugins": [
"https://plugins.dprint.dev/markdown-0.14.0.wasm"
"https://plugins.dprint.dev/markdown-0.14.1.wasm"
]
}

View file

@ -4,7 +4,7 @@ _by Mo Bitar_
So you want to learn Linux? You want to fulfill your childhood dream and look like a hacker? Or you just want to manage some servers or escape Windows or Mac for an alternative system that is [free and open source](https://www.gnu.org/philosophy/free-sw.html.en)? Then this book is for you!
This book focuses on the terminal side of Linux. This means that no [GUI](https://en.wikipedia.org/wiki/Graphical_user_interface) (graphical user interface) is discussed in this book. This makes the content of the book more useful for server usage and administration since servers normally have no GUI. Nevertheless, if you want to use Linux as a desktop, then being able to deal with the terminal is not only useful, but could even be required at some point.
This book focuses on the terminal side of Linux. This means that no [GUI](https://en.wikipedia.org/wiki/Graphical_user_interface) (graphical user interface) is discussed in this book. This makes the content more useful for server usage and administration since servers normally have no GUI. Nevertheless, if you want to use Linux as a desktop, then being able to deal with the terminal is not only useful, but could even be required at some point.
You might ask, why not just use a GUI for everything? Hopefully, this book will let you understand why. A [CLI](https://en.wikipedia.org/wiki/Command-line_interface) (command line interface) is not well suited for everything. But for many tasks, a CLI might be much more powerful. It allows automation and enables you to use it as a component to build something bigger.

View file

@ -9,6 +9,7 @@
- [Tasks](day_1/tasks.md)
- [Day 2](day_2/README.md)
- [Shell glue](day_2/glue.md)
- [Shell scripting](day_2/shell_scripting.md)
- [Tasks](day_2/tasks.md)
- [Day 3](day_3/README.md)
- [Notes](day_3/notes.md)

View file

@ -1,5 +1,5 @@
# Day 1
In this chapter, you will learn the basics of Linux in the terminal.
In this day, you will learn the basics of Linux in the terminal.
But before we start with the basics, the first section discusses why you should learn Linux in the first place.

View file

@ -8,9 +8,9 @@ Therefore, we need to learn how to install so called packages to get access to a
### Package managers
In Linux, you don't install programs by using a search engine to find a website, then visit the website and download an installer, then run the installer and click "Next" and "Agree" 100 times without even reading what you are agreeing to.
In Linux, you don't install programs by using a search engine to find a website, then visit the website and download an installer, then run the installer and click "Next" and "Agree" repeatedly without even reading what you are agreeing to 🤮
This method is too insecure. You have to trust the website that you did visit. You have to hope that no malware is delivered while you are downloading the installer from the website. You can get the malware either from the website itself or through a man-in-the-middle attack. Then the installer might do whatever it wants. You just click "Next" and suddenly your system shows you (extra) ads or your browser search preferences are overwritten with Yahoo. Surprise! 🎉
This method is too insecure. You have to trust the website that you did visit. You have to hope that no malware is delivered while you are downloading the installer from the website. You can get the malware either from the website itself or through a man-in-the-middle attack. Then the installer might do whatever it wants. You just click "Next" and suddenly your system shows you (extra) ads or your browser search preferences are overwritten by Yahoo. Surprise! 🎉
In Linux, you (mainly) install software through the package manager that ships with your distribution. The software is then downloaded from a repository which is a collection of packages that is managed by the distribution. The distribution managers make sure that no malware is added to their repositories.
@ -18,7 +18,7 @@ The package manager does take care of verifying the downloaded packages before i
The package manager does also take care of installing any other packages that you did not specify but are required by the package that you want to install. These packages are called dependencies.
Since this book uses a Fedora system for demonstrations, the book will use Fedora's package manager `dnf`.
Since this book uses a [Fedora](https://getfedora.org) system for demonstrations, the book will use Fedora's package manager `dnf`.
If you are using another Linux distribution, you might need to replace the commands of `dnf` with `apt` for Debian based distributions for example.
@ -28,7 +28,7 @@ To install a package, you need administrative privileges. Therefore, we need som
Lets install our first package! To do so, enter `sudo dnf install cmatrix`. You will be asked for the password of your user. Type the password and then press `Enter`. For security reasons, you will not be able to see you password while entering it. So don't wonder why nothing happens while typing the password. Just type it and then press `Enter`.
The package manager might need some time to sync some data, then it will show you a summary of what it will do and ask you for confirmation. Type `y` for _yes_ and then press `Enter` for the installation to start.
The package manager might need some time to synchronize some data, then it will show you a summary of what it will do and ask you for confirmation. Type `y` for _yes_ and then press `Enter` for the installation to start.
After the installation is done, you can enter `cmatrix`. Congratulations, you are a hacker now! 💻🤓
@ -36,7 +36,7 @@ To exit the matrix, press `q`.
What if you don't like the matrix and want to remove it? You can uninstall packages using `sudo dnf remove PACKAGENAME`. In this case: `sudo dnf remove cmatrix`. You have to confirm again with `y`.
Why do we speak about _packages_ instead of programs when installing software on Linux? Because packages can contain more than one binary (the actual programs) and extra files. Take a look at [the files that are installed with `cmatrix` on Fedora](https://packages.fedoraproject.org/pkgs/cmatrix/cmatrix/fedora-rawhide.html#files) for example.
Why do we speak about _packages_ instead of programs when installing software on Linux? Because packages can contain more than one binary (the actual program) and extra files. Take a look at [the files that are installed with `cmatrix` on Fedora](https://packages.fedoraproject.org/pkgs/cmatrix/cmatrix/fedora-rawhide.html#files) for example.
> Warning ⚠️ : While installing or uninstalling packages, it is important to take a look at the summary before confirming the action with `y`. There is a reason why a confirmation is required. Sometimes, some packages depend on packages with older versions than the versions that exist on your machine. If you want to install those packages anyway, other packages that depend on the newer versions can break!
>
@ -59,7 +59,7 @@ Any action that might modify the system needs administrative privileges. Install
Sometimes, an action might not modify the system, but a user might be restricted through the permissions system to not be able to access a file for example. In this case, you would also need to use `sudo`.
Linux has a superuser, one user that exists on every Linux system and is able to do anything! This user is the `root` user. For security reasons (and also to not do something destructive by a mistake), this user is often locked. `sudo` allows you as a non root user to run your command as a `root` user.
Linux has a superuser, one user that exists on every Linux system and is able to do anything! This user is the `root` user. For security reasons (and also to not do something destructive by a mistake), this user is often locked. `sudo` allows you as a non root user to run commands as a `root` user.
You are not always allowed to use `sudo`. If you don't own the machine you are using and just share it with others, then there is a high chance that only administrators of the machine have `sudo` access.
@ -73,15 +73,15 @@ If you don't have access to `sudo` and try to use it, then you get an output lik
>
> Even commands that you know like `rm` can destroy your system if you use them with `sudo` without knowing what they are doing.
>
> You might find a "meme" in the internet that tells you to run something like `sudo rm -rf /`. This command will delete EVERYTHING on your machine. It is like delete the `C` and all other drives at the same time on Windows.
> You might find a "meme" in the internet that tells you to run something like `sudo rm -rf /`. This command would delete EVERYTHING on your machine. It is like deleting the `C` and all other drives at the same time on Windows.
>
> Linux assumes that you know what you are doing when you use `sudo`. With great power comes great responsibility!
> Linux assumes that you know what you are doing when you use `sudo`. _With great power comes great responsibility!_
### Looking for a package
If you don't exactly know the name of a package you are looking for, then you can use `dnf search PATTERN`. DNF will then return packages that match the pattern in their name or description.
For example, if you search for Julia (which is a programming language, you get the following results):
For example, if you search for Julia (a programming language) you get the following results:
```console
$ dnf search julia
@ -157,7 +157,7 @@ Architecture : x86_64
(...)
```
You get too results for Julia that seem to be identical. The difference is the _architecture_. Normal computers usually have the `x86_64` architecture, so you should look for it. But it is nice to know that other architectures are also supported.
You get two results for Julia that seem to be identical. The difference is the _architecture_. Normal computers usually have the `x86_64` architecture, so you should look for it. But it is nice to know that other architectures are also supported.
If you have a problem with a package after an update, then you can try to use an older version. To do so, refer to the documentation of `dnf downgrade`.

View file

@ -39,7 +39,7 @@ Find out how to update your system with `dnf` and run the updates.
Before you confirm, make sure that you read what packages are updated. Make a screenshot of the changes.
It is possible that you don't find any update. In this case, you can try it tomorrow again!
It is possible that you don't find any updates. In this case, you can try it again on another day!
## Task 4: Package installation and usage
@ -53,8 +53,6 @@ Make a screenshot of some cow wisdom 🐮
Now install the package `lolcat`.
Lets call the wisdom command you did take the last screenshot of `COMMAND`.
Now run `COMMAND | lolcat`. Describe what changed. Can you guess how this internally works?
Lets say the wisdom command you did take the last screenshot of is `cowsay (...)`. Now run `cowsay (...) | lolcat`. Describe what changed. Can you guess how this internally works?
Now read the help of `lolcat` and find out how to add some randomness. Run the command above again with the option you found and take a screenshot after you are satisfied with the randomness you get.

View file

@ -1,6 +1,8 @@
# Terminal basics
The terminal, the console, the command line. All terms refer to the same thing. Get access to a Linux system and open a terminal.
The terminal, the console, the command line. All three terms refer to the same thing.
Get access to a Linux system and open a terminal.
Warning ⚠️ : **Don't panic!**
@ -31,11 +33,13 @@ I know, I did just brake the romance between you and your computer. I apologize.
### Navigation
Lets try more commands. type `ls` and press enter. What do you see? The output is going to be the files and directories in your current path. `ls` stands for _list_.
Lets try more commands. type `ls` and press enter. What do you see?
What if you want to take a look at the content of a different directory at different path?
The output is going to be the files and directories in your current path. `ls` stands for _list_.
To examine this, lets first create a new directory. Enter the command `mkdir empty_house`. Well, you don't see anything? Did the command do something at all? To verify this, run `ls` again. Now you should be able to see your new directory `empty_house` listed too! `mkdir` stands for _make directory_. `empty_house` is just a name for our new directory. You could have used `mkdir Images` for example to create a directory called `Images`.
What if you want to take a look at the content of a different directory at a different path?
To examine this, lets first create a new directory. Enter the command `mkdir empty_house`. Well, you don't see anything? Did the command do something at all? To verify this, run `ls` again. Now you should see your new directory `empty_house` listed too! `mkdir` stands for _make directory_. `empty_house` is just a name for our new directory. You could have used `mkdir Images` for example to create a directory called `Images`.
Is `empty_house` really empty? Lets verify that.
@ -54,11 +58,13 @@ friend1.txt
You should see the first friend of the empty directory. `touch` creates a file if it does not exist. It does also have another use case which is not relevant at this moment.
But wait a minute, our directory `empty_house` is not empty anymore! Lets fix that by renaming it.
But wait, our directory `empty_house` is not empty anymore! Lets fix that by renaming it.
Enter the command `cd ..` to go one directory back. The two dots `..` refer to the parent directory in Linux.
Now that you are back in `~`, enter `mv empty_house happy_house`. Now enter `ls` again. You can see that `empty_house` does not exist anymore. It was renamed to `happy_house` (_since it has at least one friend now_). `mv` stand for _move_. Moving is not the same as renaming, right? Well, `move` does move file or directories to a new destination while making it possible to give the file or directory a new name on the destination. So we did _move_ the directory `empty_house` to the same location, but we did give it a new name.
Now that you are back in `~`, enter `mv empty_house happy_house`. Now enter `ls` again. You can see that `empty_house` does not exist anymore. It was renamed to `happy_house` (_since it has at least one friend now_). `mv` stand for _move_.
Moving is not the same as renaming, right? Well, `mv` does move a file or directory to a new destination with the possibility to give the file or directory a new name on the destination. So we did _move_ the directory `empty_house` to the same location, but we did give it a new name.
I know, it is tricky. Lets take a look at an example that does actually _move_. Enter the command `touch friend2.txt friend3.txt`. This will create two new files at the same time. This way, you don't have to type `touch friend2.txt` **and** `touch friend3.txt`.
@ -105,7 +111,7 @@ $ rm zombies
rm: cannot remove 'zombies': Is a directory
```
So it does not work. To delete an empty directory, use `mrdir`:
So it does not work. To delete an empty directory, use `rmdir`:
```console
$ rmdir zombies
@ -130,7 +136,7 @@ What to do now? Turns out, `rm` is more powerful than we thought and can delete
What is a flag? It is an option that you specify after the command name that enables some functionality.
In our case, to remove a directory that is not empty, we need the `-r` flag of `rm`:
In our case, to remove a directory that is not empty, we need the `-r` flag (also called option) of `rm`:
```console
$ tree
@ -165,7 +171,7 @@ What you see is the path to your current directory (also called working director
We can write our rules in a simple text file. But how do we edit files in the terminal?
There are many ways to edit text files in the terminal. The simplest method is to use the command `nano`.
There are many ways to edit text files in the terminal. The simplest method is to use the editor `nano`.
Enter the command `nano rules.txt`. You will be presented with a "terminal window" showing a blinking cursor and some shortcuts at the bottom.
@ -210,7 +216,7 @@ We did use `cat` to only print the content of the file `rules.txt` without openi
### Manuals
After a while, the house might have many rules, more than the two that we did just enter. It would be useful to be able to count how many rules we do have. To do so, we can use the command `wc` which actually stands for _word count_, but is able to count more than words:
After a while, the house might have many rules, more than the two that we did just enter. It would be useful to be able to count how many rules we have. To do so, we can use the command `wc` which actually stands for _word count_, but it is able to count more than words:
```console
$ wc rules.txt
@ -219,9 +225,9 @@ $ wc rules.txt
We see three numbers. The first one is the number of lines, the second is the number of words and the last is the number of bytes. How do I know that?
I do not memorize everything! I had to look up the meaning of the three numbers. Where do you look such things up?
I do not memorize everything! I had to look up the meaning of the three numbers. Where do you look up such things?
You could use the internet, but (almost) every Linux command comes with a manual. To access the manual of a command, we use the command `man` which stands for _manual_ followed by the name of the command that we want to look up.
You could use the internet, but (almost) every Linux command comes with a manual. To access the manual of a command, we use the command `man` followed by the name of the command that we want to look up. `man` stands for _manual_.
Lets look up the command `wc`:
@ -258,11 +264,11 @@ DESCRIPTION
`(...)` indicates that parts of the output were kept out to only show relevant output here.
The structure of the output is a standard for manuals with `man`.
The structure of the output is a standard for manuals (also called _man pages_) with `man`.
The first section of the output is _NAME_ and shows the name of the command with a brief description of what it does.
The second section is _SYNOPSIS_ and shows the different way of using the command. The brackets indicate that a part is optional. The three dots `...` indicate that a part can be specified more than one time. This means that `[OPTION]...` tells us that the command accepts one to many optional options.
The second section is _SYNOPSIS_ and shows different ways of using the command. The brackets indicate that a part is optional. The three dots `...` indicate that a part can be specified more than one time. This means that `[OPTION]...` tells us that the command accepts one to many optional options.
The options are presented in the section _DESCRIPTION_ that also explains the command with more details.
@ -292,13 +298,13 @@ $ wc -l -w rules.txt
2 5 rules.txt
```
We see that we get the number of lines and then then number of words now.
We see that we get the number of lines and then the number of words.
We did learn how to access and read the manual, but do we navigate the manual?
We did learn how to access and read the manual, but how do we navigate the manual?
If you open a manual with `man`, you can scroll up and down using the arrow keys. You can search by pressing `/`, then enter what you are wanting to search, `lines` for example, and then press `Enter`.
If you open a manual with `man`, you can scroll up and down using the arrow keys. You can search by pressing `/`, then enter what you are wanting to search for, `lines` for example, and then press `Enter`.
If you get more than one match for your search, you can jump to the next match with the key `n` and to the previous one with `N` (`Shift + n`).
If you get more than one match for your search pattern, you can jump to the next match with the key `n` and to the previous one with `N` (`Shift + n`).
You can learn more about how to navigate manuals (and other so called pagers) by pressing `h` in a manual. But since a lot is derived from the editor Vi/Vim, we will learn more about it when we learn this editor later.
@ -306,7 +312,7 @@ Fun fact: You can read the manual of the manual with `man man` 😃
### Help!
If you want to read a smaller version of the manual, you can run `COMMAND --help`. Almost every command supports the `--help` flag and its small version `-h`. You will then get a quick reference.
If you want to read a smaller version of the manual, you can run `COMMAND --help`. Almost every command supports the `--help` option and its small version `-h`. You will then get a quick reference.
Try `wc --help`!
@ -320,11 +326,11 @@ $ mkdir new_house
$ cd new_house
```
We did not use any new command, but what is this symbol `~`? We did already mention it and you might have noticed that it was showed in the prompt after opening the terminal. The so called tilde `~` stands for your home in Linux. Your home as a user has the path `/home/USERNAME` and it is the directory where you should place your own files.
We did not use any new commands, but what is this symbol `~`? We did already mention it and you might have noticed that it was shown in the prompt after opening the terminal. The so called tilde `~` stands for your home in Linux. Your home as a user has the path `/home/USERNAME` and it is the directory where you should place your own files.
By entering `cd ~`, we did make sure that we are in our "home" before creating a new directory. Enter only `cd` does have the same effect as `cd ~`.
By entering `cd ~`, we did make sure that we are in our "home" before creating a new directory. Entering only `cd` does have the same effect as `cd ~`.
So we did create a new house directory and did move into it. Lets say, we want to copy the rules from the first house to the new one while we are in the new one. To do so, we can use the command `cp` that stand for _copy_:
So we did create a new house directory and move into it. Lets say we want to copy the rules from the first house to the new one while we are in the new one. To do so, we can use the command `cp` that stand for _copy_:
```console
$ pwd
@ -339,9 +345,9 @@ No loud housemates!
We did copy the rules, but did you notice the dot at the end of the command `cp`? What does it mean?
We did learn that `..` refers to the parent directory (one directory back). `.` refers to the current directory.
We did learn that the two dots `..` refer to the parent directory (one directory back). One dot `.` refers to the current directory.
Here are some equivalent commands that might help you understand paths in Linux:
Here are some **equivalent** commands that might help you understand paths in Linux:
1. `cp /home/USERNAME/happy_house/rules.txt /home/USERNAME/new_house/rules.txt`
2. `cp ~/happy_house/rules.txt ~/new_house/rules.txt`
@ -351,15 +357,15 @@ Here are some equivalent commands that might help you understand paths in Linux:
All the commands above do the same thing. The difference is the way we did specify the source and destination path.
The 1. command is the most verbose one. We specify the full path of the source and destination.
The **1. command** is the most verbose one. We specify the full path of the source and destination.
In the 2. command, we did use `~` which is a shortcut to `/home/USERNAME`.
In the **2. command**, we use `~` which is a shortcut to `/home/USERNAME`.
In the 3. command, we did remove the file name from the destination path. If a file name is not specified in the destination path, then the file name from the source is used.
In the **3. command**, we remove the file name from the destination path. If a file name is not specified in the destination path, then the file name from the source is used.
In the 4. command, we did use the dot `.` as a shortcut to the current directory since we are currently in the directory `new_house`.
In the **4. command**, we use the dot `.` as a shortcut to the current directory since we are currently in the directory `new_house`.
In the 5. command, we did use the two dot `..` instead of `~` which is also possible since the parent directory is `~` in this case. The double dot is useful we are operating in directories that are nested deeper in your home.
In the **5. command**, we use the two dots `..` instead of `~` which is also possible since the parent directory is `~` in this case. The two dots are useful when we are operating in directories that are nested deeper in the home directory.
You might think: `.` is the path to the current directory. `..` is the path of the parent directory. Is `...` the path of the parent directory of the parent directory? Lets try it out:
@ -372,20 +378,20 @@ $ ls ...
ls: cannot access '...': No such file or directory
```
So this does not work. Anything number of dots greater that 2 does not word, except if we use separators. To access the parent directory of the parent directory, you can use `../..`:
So this doesn't work. Any number of dots greater that 2 doesn't work, except if we use separators. To access the parent directory of the parent directory, you can use `../..`:
```console
$ ls ../..
USERNAME (...)
```
You will probably only see your user name as output, but if the system you are using has more than one user, then names of the other users would be in the output, too. Every user has his own home directory under `/home`.
You will probably only see your user name as output, but if the system you are using has more than one user, then names of the other users would be in the output, too. Every user has an own home directory under `/home`.
The usage of `../..` or even more dots like `../../..` is not recommended since you would have to go multiple directories up in your mind and this does not work well! Use the full path for paths not in the current `.` or in the parent directory `..`.
What we have just learned about paths does not only apply to `cp`, but also to `ls`, `mkdir`, `mv` and other commands that deal with paths.
One thing has to be mentioned about `cp`: To copy directories instead of just files, use the option/flag `-r` to copy recursively like with `rm`.
One thing has to be mentioned about `cp`: To copy directories instead of just files, use the option `-r` to copy recursively like with `rm`.
### Terminal shortcuts
@ -395,7 +401,7 @@ If you have another directory in your home that is called something like `happy_
Often, commands are not long, but you can use autocompletion to complete commands too. If you type `ech` and then press `Tab`, you get the autocompletion `echo` with the space at the end to enter options or arguments. In this case, we did only save entering one character and a space, so `echo` is not the best opportunity for autocompletion. But this is only a demonstration. Some commands might be longer.
You might think that you don't need autocompletion at all. But you should use it. Not only for autocompletion, but for verification!
You might think that you don't need autocompletion at all. But you should use it. Not only for the autocompletion itself, but for verification, too!
When you type `cat hapy_house/ru` and then press `Tab`, you don't get any autocompletion although you would expect it. But did you notice the missing `p` in `happy`?
@ -403,9 +409,9 @@ This is meant by verification. If you don't get an autocompletion although you t
But what if you did run a command with a mistake and you have to correct it? Or what if you want to run the same command with small modifications? Do you have to type the whole command again?
Fortunately, no! You can use the up and down arrows to navigate through your commands history. Try it out!
Fortunately, no! You can use the up ⬆️ and down ⬇️ arrow keys to navigate through your commands history. Try it out!
If you started typing a command and you did notice that you did miss something in the middle of the command, you might try to use the mouse and click. No clicks will help you! Instead, use the left and right arrow keys.
If you started typing a command and you did notice that you did miss something in the middle of the command, you might try to use the mouse and click. No clicks will help you! Instead, use the left ⬅️ and right ➡️ arrow keys.
If you want to go to the beginning of the command, press `Ctrl + a`. Then you can go back to the end with `Ctrl + e`.
@ -429,11 +435,11 @@ Enter `python3 nonstop.py` to run the code.
Annoying, right? To stop a running program, press `Ctrl + c`. You _have to_ remember this shortcut!
You can also use `Ctrl + c` if are typing a command and you want to start over. Instead of pressing `Backspace` for a long time, just press `Ctrl + c`!
If you are typing a command and want to start over, you can use `Ctrl + c` instead of pressing `Backspace` repeatedly.
But wait, `Ctrl + c` is (normally) used for copying, right?
No, not in the terminal. If you want to copy text in the terminal, then select it with the mouse and the press `Ctrl + Shift + C`.
No, not in a terminal. If you want to copy text in a terminal, then select it with the mouse and the press `Ctrl + Shift + C`.
To paste text into the terminal, press `Ctrl + Shift + v`.

View file

@ -1,3 +1,3 @@
# Day 2
Coming soon...
In this day, we will learn how to glue commands together to benefit from their modularity. Later, we will write our own shell scripts to achieve some automation.

View file

@ -1,8 +1,8 @@
# Shell glue
When you run something in the terminal, then you are interacting with the so called `shell`.
When you run something in the terminal, then you are interacting with the so called _shell_.
The default shell on almost all Linux systems is `bash`. (We will learn about the `fish` shell later)
The default shell on almost all Linux systems is `bash`. (We will learn about the `fish` shell later 🐠)
The shell has the power to glue commands together to make the impossible possible! Lets use some gluing magic!
@ -28,18 +28,18 @@ Lets count the number of lines of the html file of the homepage of this book:
```console
$ curl -s https://how-to-linux.mo8it.xyz | wc -l
201
220
```
The option `-s` tells `curl` to be silent and not show progress information.
You can see that `wc` did count the number of lines. We did just combine two completely different tools with some pipes glue!
How about counting the number times the word "Linux" was mentioned on the homepage?
How about counting the number of lines that contain the word "Linux" on the homepage?
To do so, we will add a new pipe inbetween!
`grep` is a command that searches for matches of a specified pattern. Each match is printed in a new line.
`grep` is a command that searches for matches of a specified pattern. Each line with a match is printed in a new line.
To demonstrate `grep`, here is an usage example:
@ -55,14 +55,14 @@ Back to the main example:
```console
$ curl -s https://how-to-linux.mo8it.xyz | grep "Linux" | wc -l
6
7
```
You can see that you can use multiple pipes. This allows for almost infinite combinations!
Being able to combine commands is the reason why many commands are simple. They do one thing and do it well! To do more, combine them!
This is much more flexible and powerful that a program that tries to do a lot of things.
This is much more flexible and powerful than a program that tries to do a lot of things.
## Input, output
@ -74,24 +74,24 @@ The standard output has the number 1 while the standard error has the number 2.
Normal output is sent to the standard output. Errors (and sometimes output that is not very important) are sent to the standard error.
You can redirect the standard output or the standard error to a _stream_. Normally you will redirect the output to a file. Other stream forms are not relevant for now.
You can redirect the standard output or the standard error to a file!
## Redirections
Lets see how you can redirect the output of commands to a file.
If you just run `curl -s https://how-to-linux.mo8it.xyz`, you will the html file printed in the terminal. Lets redirect the output to a html file on your disk:
If you just run `curl -s https://how-to-linux.mo8it.xyz`, you will see the html file printed to the terminal. Lets redirect the output to a html file on your disk:
```console
$ curl -s https://how-to-linux.mo8it.xyz > how-to-linux.html
```
Now view the content of the new file how-to-linux.html. You will be able to see the same output from the terminal without redirection.
Now view the content of the new file `how-to-linux.html`. You will see the same output from the terminal without redirection.
Now try this command:
```console
$ curl https://not-existent-site.mo8it.xyz > test.html
$ curl https://non-existent-site.mo8it.xyz > test.html
curl: (60) SSL certificate problem: self-signed certificate
More details here: https://curl.se/docs/sslcerts.html
@ -106,7 +106,7 @@ You will see that the file is empty since `curl` did not find a page to show as
If you are using this command in a script, then it might be wise to redirect the error to a log file:
```console
$ curl https://not-existent-site.mo8it.xyz 2> curl.log
$ curl https://non-existent-site.mo8it.xyz 2> curl.log
$ cat curl.log
curl: (60) SSL certificate problem: self-signed certificate
More details here: https://curl.se/docs/sslcerts.html
@ -123,44 +123,3 @@ Did you notice the number 2 before the redirection symbol `2>`?
The last section did mention that the number of the standard error is 2. Therefore, 2 has to be specified to redirect the errors.
If you don't specify a number, then it is equivalent to 1 which stands for the standard output. This means that `>` is equivalent to `1>`.
## Bash scripts
Lets write our first Bash script (also for some more demonstration of the two outputs):
```bash
#!/usr/bin/bash
echo "What is your favorite operating system after reading this book?"
echo "1. Linux"
echo "2. Windows"
echo "3. Mac"
echo -n "Enter a number: "
read ANSWER
if [ "$ANSWER" == "1" ]
then
echo "Good choice!"
else
echo "Nah, that can't be right! It must be an error!" > /dev/stderr
fi
```
Copy this code into a file called `which-os.sh`.
Now run `chmod +x which-os.sh`. Then run `./which-os.sh`.
---
I am really sorry, but I can not continue this book during the course. It was not only meant for the course but also like a personal project that I wanted to keep on the internet even after the course.
But I did underestimate the huge amount of time it takes to write such a book/script.
Continuing the book during the course would mean that I can not cover a lot of topics because I can not write enough. It would also harm my health. I need sleep :')
I will continue it after the course, not only for the participants as output, but also for the purpose of a personal project. So please don't be disappointed. You will find all contents on this website some time after the course. I hope that it would then help you as a resource for looking things up.
I do especially apologize to the online participants. I did give my best.
Again, it is not lost. You will get it, but after the course :)

View file

@ -0,0 +1,337 @@
# Shell scripting
Task automation requires multiple instructions that have to run on demand. To combine multiple instructions, we need to write a shell script.
Since `bash` is the default shell on most Linux distributions, we learn bash scripting.
## First bash script
Lets write our first Bash script:
```bash
#!/usr/bin/bash
echo "What is your favorite operating system after reading this book?"
echo "1. Linux"
echo "2. Windows"
echo "3. Mac"
RIGHT_ANSWER=1
# The option -n does not print a new line at the end
echo -n "Enter a number: "
read ANSWER
if [ $ANSWER == $RIGHT_ANSWER ]
then
echo "Good choice!"
else
# Any answer other than 1
echo "Nah, that can't be right! It must be an error!" 1>&2
fi
```
Copy this code into a file called `which-os.sh`.
Now run `chmod u+x which-os.sh`. Then run `./which-os.sh`. Don't worry, everything will be explained afterwards.
After running the script, you will see a prompt asking you to enter a number corresponding to an operating system. If you choose Linux, you get the output "Good choice". This output is in the standard output.
If you don't choose Linux, you get the output "Nah, that can't be right! (...)". This output is redirected to the standard error.
We did learn that we can redirect to a file using `>`. The syntax `1>&2` redirects the standard output to the standard error. On the other hand. `2>&1` redirects the standard error to the standard output.
If you want to redirect both the standard output and error to a file, you can use this syntax: `COMMAND > FILE 2>&1`.
The redirection **order** is important in this case! `COMMAND 2>&1 > FILE` will redirect the standard output **only** to the file `FILE`!
`COMMAND > FILE 2>&1` has a useful shortcut: `COMMAND &> FILE`. You can also use `&>>` to append.
All other aspects of the script above will be explained in the next sections.
## Shebang
The first line of our first script starts with `#!` which is called the _shebang_. The shebang is followed by the program that runs the script. Since the script is a bash script, we use the program `bash` to run it. But writing `bash` after the shebang is not enough. We have to specify the path to the program. We can find out the path of the program by using the command `which`:
```console
$ which bash
/usr/bin/bash
```
You can also write a Python script and add a shebang at its beginning. We can find out the path to the Python program:
```console
$ which python3
/usr/bin/python3
```
This means that we can now write this script:
```python
#!/usr/bin/python3
print("Hello world!")
```
Lets save this tiny Python script as `hello_world.py`, make it executable with `chmod` (will be explained later) and then run it:
```console
$ chmod u+x hello_world.py
$ ./hello_world.py
Hello world!
```
We could have written the Python script without the shebang, but then we would have to run with `python3 hello_world.py`. Adding the shebang lets you see a script as a program and ignore what language it is written in when running it.
You can use the shebang with any program that runs a script (interpreter).
## Variables
In our first bash script, we have the line `RIGHT_ANSWER=1`. This line defines a variable with the name `RIGHT_ANSWER` and the value `1`.
To define a variable in bash, you have to write the name of the variable _directly_ followed by an equal sign `=`. The equal sign has to be _directly_ followed by the value of the variable.
_directly followed_ means that spaces between the variable name, the equal sign `=` and the value are not allowed!
But what if you want to set a variable equal to a string that contains spaces?
In this case, you have to use quotation marks `"`. For example:
```bash
HELLO="Hello world!"
```
To use a defined variable, we use a dollar sign `$` before the variable name. For example:
```bash
echo $HELLO
```
The line above would output `Hello world!`.
You can use defined variable inside a variable definition:
```bash
MESSAGE="Tux says: $HELLO"
echo $MESSAGE
```
The two lines above would lead to the output `Tux says: Hello world!`.
## Capturing command's output
You can capture the standard output of a command using the the syntax `$(COMMAND)`. Example:
```bash
BASH_VERSION=$(bash --version)
```
The line above saves the output of the command `bash --version` in the variable `BASH_VERSION`.
Lets run the command in the terminal first to see its output:
```console
$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://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.
```
Now lets output the variable that we did define above:
```console
$ echo $BASH_VERSION
GNU bash, version 5.1.16(1)-release (x86_64-redhat-linux-gnu) Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://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.
```
You can see that the lines are squashed into one line! If you want to output the lines without them being squashed, you have to use quotation marks `"`:
```console
$ echo "$BASH_VERSION"
GNU bash, version 5.1.16(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://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.
```
This is the output that we did expect 😃
## Temporary variables
Lets write the following tiny script `hello.sh`:
```bash
#!/usr/bin/bash
echo "Hello $USER!"
```
Now we run the script. The output on my machine is:
```console
$ chmod u+x hello.sh
$ ./hello.sh
Hello mo!
```
We see `Hello mo!` as output. This is because my user name on my machine is `mo`. `USER` is a so called environment variable that is defined for all programs. If you run the script on your machine, you will get your user name instead of `mo`. There are more environment variables like `PATH` which we will learn about later.
Now lets run the following:
```console
$ USER=Tux ./hello.sh
Hello Tux!
```
We did define a temporary variable `USER` with the value `Tux`. This temporary variable overwrites the environment variable `USER` in our script. Therefore we get the output `Hello Tux!` and not our user name.
You can use temporary variables not only to overwrite environment variables. These are basically variables that can be used by the program that you specify after their definition.
## Comments
In our first bash script, you can find three lines starting with a hashtag `#`. Two lines are comments, the shebang `#!` is an exception as a special comment at the beginning of a file that is not ignored while running the script. All other lines that start with `#` are comments that are ignored by the computer. Comments are only for humans to explain things.
Especially in long scripts, you should write comments to explain what the script and its "non trivial sections" do.
## User input
In a script, you can ask for user input. To do so, you can use the command `read`.
In our first bash script, we use `read` to take the answer of the user. The input is then saved in the variable `ANSWER`. You can choose a different name for this variable. After the line with `read`, you can use the variable storing the input as a normal variable.
## Conditions
### `if` block
Our first bash script checks if the user input which is stored in the variable `ANSWER` equals the variable `RIGHT_ANSWER` which stores the value `1`.
To check for a condition in Bash, we use the following syntax:
```bash
if [ CONDITION ]
then
(...)
fi
```
Here, `(...)` stands for the commands that we want to run if the condition is true.
In our first bash script, we check for equality of two variables with a double equal sign `==`.
`fi` is not a typo! It is just `if` reversed to indicate the end of the `if` block. Although the syntax is not the best, you have to sadly accept it. Bash does not have the best syntax...
Speaking about syntax: You have to take spaces seriously with conditions.
For example, if we define the variable `VAR=1`, the following snippets **do not work** (or have an unexpected behavior):
1. No space after `[`
```bash
if [$VAR == 1 ]
then
echo "VAR has the value 1"
fi
```
1. No space before `]`
```bash
if [ $VAR == 1]
then
echo "VAR has the value 1"
fi
```
1. No space before `==` but a space after `==`
```bash
if [ $VAR== 1 ]
then
echo "VAR has the value 1"
fi
```
1. No space after `==` but a space before `==`
```bash
if [ $VAR ==1 ]
then
echo "VAR has the value 1"
fi
```
1. No space before `==` and after `==`
```bash
if [ $VAR==1 ]
then
echo "VAR has the value 1"
fi
```
But the following snippet **work**:
- Space after `[`, before `]`, before `==` and after `==`
```bash
if [ $VAR == 1 ]
then
echo "VAR has the value 1"
fi
```
### `else` block
The `else` block runs commands inside it only if the condition is not true. The syntax is:
```bash
if [ CONDITION ]
then
# Runs only if CONDITION is true
(...)
else
# Runs only if CONDITION is false
(...)
fi
```
Example:
```bash
if [ $VAR == 1 ]
then
echo "VAR has the value 1"
else
echo "VAR does not have the value 1"
fi
```
<!-- TODO: else -->
<!-- TODO: else if -->
<!-- TODO: test -->
<!-- TODO: if [ ! -f ] -->
<!-- TODO: case -->
<!-- TODO: for -->
<!-- TODO: while -->
<!-- TODO: command | while read -->
<!-- TODO: math (( )) -->
<!-- TODO: Long command on multiple lines \ -->
<!-- Why ./SCRIPT_NANEM -->
<!-- TODO: Permissions -->
<!-- TODO: r,w,x -->
<!-- TODO: u,g,o -->
<!-- TODO: chmod codes -->
<!-- TODO: https://chmodcommand.com -->
Rest coming soon...

File diff suppressed because one or more lines are too long