diff --git a/jupyterhub_volumes/course/unix.ipynb b/jupyterhub_volumes/course/unix.ipynb
new file mode 100644
index 0000000..9de4ff6
--- /dev/null
+++ b/jupyterhub_volumes/course/unix.ipynb
@@ -0,0 +1,142 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Unix Essentials — Bash Exercises\n",
+ "\n",
+ "This notebook contains short hands-on Bash exercises.\n",
+ "Each exercise has a hidden solution that can be unfolded when needed."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Exercise 1 – Listing and Filtering Files\n",
+ "\n",
+ "Create three files and list only those whose name ends with `.log`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# your work here\n",
+ "touch report.log notes.txt errors.log\n",
+ "# list files ending with .log"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "jupyter": {
+ "source_hidden": true,
+ "outputs_hidden": true
+ }
+ },
+ "outputs": [],
+ "source": [
+ "# Solution\n",
+ "ls *.log"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Exercise 2 – Redirecting Output\n",
+ "\n",
+ "List the `/etc` directory and save the results in a file named `listing.txt`, then display the first five lines of that file."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# your work here\n",
+ "# 1. list /etc\n",
+ "# 2. redirect output to listing.txt\n",
+ "# 3. show first five lines"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "jupyter": {
+ "source_hidden": true,
+ "outputs_hidden": true
+ }
+ },
+ "outputs": [],
+ "source": [
+ "# Solution\n",
+ "ls /etc > listing.txt\n",
+ "head -5 listing.txt"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Exercise 3 – Using a For Loop\n",
+ "\n",
+ "Write a loop that prints the line count of each `.txt` file in the current directory."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# your work here\n",
+ "# hint: use wc -l"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "jupyter": {
+ "source_hidden": true,
+ "outputs_hidden": true
+ }
+ },
+ "outputs": [],
+ "source": [
+ "# Solution\n",
+ "for f in *.txt; do\n",
+ " echo \"$f: $(wc -l < \"$f\") lines\"\n",
+ "done"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "---\n",
+ "All solutions are hidden by default (`source_hidden: true`). Students can unfold them in Jupyter’s interface to compare with their own answers."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Bash",
+ "language": "bash",
+ "name": "bash"
+ },
+ "language_info": {
+ "name": "bash"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/obijupyterhub/Dockerfile b/obijupyterhub/Dockerfile
index cc95d53..76b1b60 100644
--- a/obijupyterhub/Dockerfile
+++ b/obijupyterhub/Dockerfile
@@ -8,6 +8,7 @@ RUN apt-get update && apt-get install -y \
r-base r-base-dev \
libcurl4-openssl-dev libssl-dev libxml2-dev \
build-essential git curl \
+ texlive-xetex texlive-fonts-recommended texlive-plain-generic \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Install R kernel + useful packages
diff --git a/web_src/lectures/computers/unix/commande-tube.svg b/web_src/lectures/computers/unix/commande-tube.svg
new file mode 100644
index 0000000..a58abe0
--- /dev/null
+++ b/web_src/lectures/computers/unix/commande-tube.svg
@@ -0,0 +1,148 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/commande.svg b/web_src/lectures/computers/unix/commande.svg
new file mode 100644
index 0000000..a8650f3
--- /dev/null
+++ b/web_src/lectures/computers/unix/commande.svg
@@ -0,0 +1,167 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/fs-link.svg b/web_src/lectures/computers/unix/fs-link.svg
new file mode 100644
index 0000000..fe76580
--- /dev/null
+++ b/web_src/lectures/computers/unix/fs-link.svg
@@ -0,0 +1,3245 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/fs-spdir.svg b/web_src/lectures/computers/unix/fs-spdir.svg
new file mode 100644
index 0000000..3568aa2
--- /dev/null
+++ b/web_src/lectures/computers/unix/fs-spdir.svg
@@ -0,0 +1,2341 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/fs.svg b/web_src/lectures/computers/unix/fs.svg
new file mode 100644
index 0000000..774be42
--- /dev/null
+++ b/web_src/lectures/computers/unix/fs.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/web_src/lectures/computers/unix/gnome-fs-directory.svg b/web_src/lectures/computers/unix/gnome-fs-directory.svg
new file mode 100644
index 0000000..1d72ff6
--- /dev/null
+++ b/web_src/lectures/computers/unix/gnome-fs-directory.svg
@@ -0,0 +1,343 @@
+
+
+
+
+
diff --git a/web_src/lectures/computers/unix/gnome-fs-home.svg b/web_src/lectures/computers/unix/gnome-fs-home.svg
new file mode 100644
index 0000000..377748b
--- /dev/null
+++ b/web_src/lectures/computers/unix/gnome-fs-home.svg
@@ -0,0 +1,350 @@
+
+
+
+
+
diff --git a/web_src/lectures/computers/unix/gnome-fs-regular.svg b/web_src/lectures/computers/unix/gnome-fs-regular.svg
new file mode 100644
index 0000000..47012e4
--- /dev/null
+++ b/web_src/lectures/computers/unix/gnome-fs-regular.svg
@@ -0,0 +1,260 @@
+
+
+
+
+
diff --git a/web_src/lectures/computers/unix/gnome-fs-slink.svg b/web_src/lectures/computers/unix/gnome-fs-slink.svg
new file mode 100644
index 0000000..6a4c71a
--- /dev/null
+++ b/web_src/lectures/computers/unix/gnome-fs-slink.svg
@@ -0,0 +1,306 @@
+
+
+
+
+
diff --git a/web_src/lectures/computers/unix/unix_lecture.qmd b/web_src/lectures/computers/unix/lecture_unix.qmd
similarity index 91%
rename from web_src/lectures/computers/unix/unix_lecture.qmd
rename to web_src/lectures/computers/unix/lecture_unix.qmd
index 8c59ecb..75a643c 100644
--- a/web_src/lectures/computers/unix/unix_lecture.qmd
+++ b/web_src/lectures/computers/unix/lecture_unix.qmd
@@ -5,7 +5,7 @@ format:
toc: true
toc-depth: 3
code-tools: true
- code-fold: true
+ code-fold: false
---
# Introduction to Unix
@@ -43,6 +43,7 @@ This user information is typically stored in the system's `/etc/passwd` file, a
```{bash}
#| label: passwd
+#| eval: false
#| caption: >
#| Sample excerpt from an /etc/passwd file. Each line represents one user account,
#| with fields separated by colons. The fields show, in order: username,
@@ -52,6 +53,26 @@ This user information is typically stored in the system's `/etc/passwd` file, a
cat /etc/passwd | head -15
```
+```{bash}
+#| echo: false
+#| output: asis
+echo "root:x:0:0:root:/root:/bin/bash
+daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
+bin:x:2:2:bin:/bin:/usr/sbin/nologin
+sys:x:3:3:sys:/dev:/usr/sbin/nologin
+sync:x:4:65534:sync:/bin:/bin/sync
+games:x:5:60:games:/usr/games:/usr/sbin/nologin
+man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
+lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
+mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
+news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
+uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
+proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
+www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
+backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
+list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin"
+```
+
## The File System
@@ -63,6 +84,7 @@ In a Unix system, a file name describes a path in a tree. A file name begins wit
```{bash}
#| label: fig-fs-unix
+#| eval: false
#| fig-cap: >
#| Example of part of the hierarchy of a Unix file system: The path marked in
#| red corresponds to the filename `/etc/passwd`. This file contains all the
@@ -71,6 +93,30 @@ In a Unix system, a file name describes a path in a tree. A file name begins wit
tree -L 2 /
```
+```
+/
+├── bin -> usr/bin
+├── boot
+├── dev
+├── etc
+│ ├── passwd
+│ ├── group
+│ └── ...
+├── home
+│ ├── user1
+│ └── user2
+├── proc
+├── root
+├── tmp
+├── usr
+│ ├── bin
+│ ├── lib
+│ └── ...
+└── var
+ ├── log
+ └── ...
+```
+
This naming system leads to saying that all files in a Unix system are arranged in a tree structure. In this structure, each internal node is designated as a directory, and each leaf of the tree is either a file or an empty directory.
This tree structure contains certain directories that are found in many Unix systems. Among these we can mention:
@@ -97,6 +143,7 @@ The concept of a link (*link* in English) can be assimilated to the concept of a
```{bash}
#| label: fig-fs-link
+#| eval: false
#| fig-cap: >
#| `/home/bar/programs` a link to the directory `/usr/bin`:
#| The special file `/home/bar/programs` is a so-called *symbolic*
@@ -106,6 +153,14 @@ The concept of a link (*link* in English) can be assimilated to the concept of a
ls -la /home/bar/
```
+```
+total 12
+drwxr-xr-x 3 bar users 4096 Jan 15 10:30 .
+drwxr-xr-x 4 root root 4096 Jan 10 14:22 ..
+lrwxrwxrwx 1 bar users 8 Jan 15 10:30 programs -> /usr/bin
+-rw-r--r-- 1 bar users 123 Jan 15 10:25 document.txt
+```
+
#### The Directories "." and ".."
{#point-pointpoint}
@@ -113,11 +168,20 @@ The Unix system uses this link system to facilitate the use of the file name tre
```{bash}
#| label: fig-fs-spdir
+#| eval: false
#| fig-cap: The links "." and ".." allow moving up the tree.
ls -la
```
+```
+total 4
+drwxr-xr-x 3 user users 4096 Jan 15 10:30 .
+drwxr-xr-x 4 user users 4096 Jan 10 14:22 ..
+-rw-r--r-- 1 user users 123 Jan 15 10:25 file1.txt
+-rw-r--r-- 1 user users 456 Jan 15 10:26 file2.txt
+```
+
These links mean that for each file there is not one name but an infinity of possible names. The file `/home/bar/my_file` can also be named:
- `/home/bar/./my_file`
@@ -176,6 +240,7 @@ To give a concrete aspect to our process, we can consider that it corresponds to
```{bash}
#| label: fig-process-anatomy
+#| eval: false
#| fig-cap: >
#| Anatomy of a process: a process can be divided into three main parts
#| that it inherits from its parent.
@@ -183,13 +248,22 @@ To give a concrete aspect to our process, we can consider that it corresponds to
ps aux
```
+```
+USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
+root 1 0.0 0.0 168016 10832 ? Ss Jan15 0:01 /sbin/init
+root 2 0.0 0.0 0 0 ? S Jan15 0:00 [kthreadd]
+root 3 0.0 0.0 0 0 ? I< Jan15 0:00 [rcu_gp]
+user 1234 0.1 0.5 172340 44512 pts/0 Ss 10:30 0:00 bash
+user 5678 0.0 0.2 162324 23456 pts/0 R+ 10:31 0:00 ps aux
+```
+
#### The Environment of a Process
A process is an isolated memory area from the rest of the machine in which a program executes. The isolation secures the computer by preventing a program from corrupting the execution of others. Nevertheless, a program must during its execution interact with the rest of the computer, for example to retrieve the data on which it will work and return the results of these calculations.
The environment of a process is dedicated to this interface task between the process and the rest of the system. It contains the description of the system elements that must be known to the process. Roughly, two main types of information are stored in a process's environment: environment variables and streams.
-Environment variables make it possible to associate a name with a value describing certain properties of the system. Some of these variables are of very general use, such as `CWD` which contains the "Current Working Directory" used for interpreting relative paths or `PATH` which contains the list of directories where the programs available on the machine are stored. Other variables have a more restricted use, for example `BLASTMAT` and `BLASTDB` are two environment variables used by the `blast` program from NCBI^[http://blast.ncbi.nlm.nih.gov/]. It is possible to obtain the list of environment variables set by the `env` command (page @unix-env). The Unix command to define or modify an environment variable depends on the Unix *shell* you are using. Under `csh` the command is `setenv` (page @unix-setenv).
+Environment variables make it possible to associate a name with a value describing certain properties of the system. Some of these variables are of very general use, such as `CWD` which contains the "Current Working Directory" used for interpreting relative paths or `PATH` which contains the list of directories where the programs available on the machine are stored. Other variables have a more restricted use, for example `BLASTMAT` and `BLASTDB` are two environment variables used by the `blast` program from NCBI^[http://blast.ncbi.nlm.nih.gov/]. It is possible to obtain the list of environment variables set by the `env` command (page @unix-env). The Unix command to define or modify an environment variable depends on the Unix *shell* you are using. Under `bash` the command is `export` (page @unix-export).
Streams are virtual pipes through which data flows. A stream operates either in reception or in data transmission. The other end of this pipe is directed either to a file or to another process. Streams, often called "*pipe*" in the Unix world, are the preferred means of data transmission between two processes working together. By default, at least three streams are associated with each process. The standard input stream "*stdin*" through which a Unix program normally receives its data, the standard output stream "*stdout*" which is used by the program to return its results, and the standard error output "*stderr*" used for transmitting error messages and information generated by the program during its execution. The use of these three streams is a Unix convention. A Unix system user therefore expects the program they are using to follow this standard. But it is the responsibility of the program designer to follow it, so some programs do not follow this model, which can sometimes confuse the uninformed user. Whenever a Unix program opens a file to read or write data, it actually modifies its environment by adding a new stream through which it can communicate with the rest of the system.
@@ -217,6 +291,7 @@ Figure @fig-process-life presents graphically the stages of creation and destruc
```{bash}
#| label: fig-process-life
+#| eval: false
#| fig-cap: >
#| Life and death of a process: Every process inherits through a more or less
#| long chain of calls to the `fork` system function from the initial process
@@ -233,22 +308,33 @@ Figure @fig-process-life presents graphically the stages of creation and destruc
pstree
```
+```
+systemd─┬─NetworkManager───2*[{NetworkManager}]
+ ├─accounts-daemon───2*[{accounts-daemon}]
+ ├─avahi-daemon───avahi-daemon
+ ├─bash───pstree
+ ├─cron
+ ├─dbus-daemon
+ └─2*[systemd───(sd-pam)]
+```
+
The normal chronology to create a new process is to call the `fork` function, to test after this call in which process the program continues its execution. In the child process, you must then call the `exec` function to replace the old program of the new process with the code of the new program to be executed. At the end of this execution, the parent is notified of the end of its child, it definitively releases the process.
## The Shell - A Working Environment
The shell is the most important program for a Unix user. It is through it that they interact with their computer. There is a graphical window system under Unix similar to those encountered under Windows or macOS, it is called XWindows or abbreviated X11. It has the advantage of functioning in client/server mode across the network. This means for a user that their program can run on one machine while they interact with it via their control windows from a second machine. However, we will not talk about this system further in this Unix presentation and we will content ourselves with interacting with our Unix machine in "text" mode via the shell.
-The Unix shell^[a shell, i.e., a small protected space in a large Unix machine from which it is possible to work] is a program capable of interpreting a command language. These commands allow the user to launch the execution of a program by specifying to it the data on which it must work, possibly some parameters to adjust its execution, and what should be done with the results. There are many shells. What differentiates them is that their command language is not strictly identical. Two shells are mainly used today: `bash` for "Bourn again shell" which is the modern version of the Bourn shell^[Bash website: http://www.gnu.org/software/bash] (`sh`) and `tcsh` for "Turbo C-Shell" the modern version of the C-Shell^[tcsh website: http://www.tcsh.org/Welcome] (`csh`). Other shells exist such as the Korn shell (`ksh`) developed by David Korn in the early 1980s or the Z-Shell (`zsh`) written by Paul Falstad in 1990 which is another improved version of the Bourn-Shell. Most of these shells allow performing the same operations but sometimes using different syntaxes. Some people prefer one or the other but their reasons are most often subjective. In the rest of this presentation, we will only use `tcsh`. By default on most Unix machines, the two shells: `bash` and `tcsh` are installed. When you connect to a Unix machine, one of the two is launched for you by default. It is possible to change your default shell using the `chsh` command (see page @unix-chsh) or to switch from one shell to another using the commands `bash` (see page @unix-bash) and `tcsh` (see page @unix-tcsh).
+The Unix shell^[a shell, i.e., a small protected space in a large Unix machine from which it is possible to work] is a program capable of interpreting a command language. These commands allow the user to launch the execution of a program by specifying to it the data on which it must work, possibly some parameters to adjust its execution, and what should be done with the results. There are many shells. What differentiates them is that their command language is not strictly identical. Two shells are mainly used today: `bash` for "Bourn again shell" which is the modern version of the Bourn shell^[Bash website: http://www.gnu.org/software/bash] (`sh`) and `tcsh` for "Turbo C-Shell" the modern version of the C-Shell^[tcsh website: http://www.tcsh.org/Welcome] (`csh`). Other shells exist such as the Korn shell (`ksh`) developed by David Korn in the early 1980s or the Z-Shell (`zsh`) written by Paul Falstad in 1990 which is another improved version of the Bourn-Shell. Most of these shells allow performing the same operations but sometimes using different syntaxes. Some people prefer one or the other but their reasons are most often subjective. In the rest of this presentation, we will only use `bash`. By default on most Unix machines, the two shells: `bash` and `tcsh` are installed. When you connect to a Unix machine, one of the two is launched for you by default. It is possible to change your default shell using the `chsh` command (see page @unix-chsh) or to switch from one shell to another using the commands `bash` (see page @unix-bash) and `tcsh` (see page @unix-tcsh).
### Basic Structure of a Unix Command
-A shell is therefore a program that interprets a computer language that allows easily launching the execution of other programs by indicating to them where to find their data and what to do with the results they produce. This language, like all others, has a vocabulary and a grammar. The languages of the different shells can be considered as dialects of the same language. Also, there are great similarities between them. All the explanations we provide here concern `tcsh` but for the most part, they are applicable to other shells.
+A shell is therefore a program that interprets a computer language that allows easily launching the execution of other programs by indicating to them where to find their data and what to do with the results they produce. This language, like all others, has a vocabulary and a grammar. The languages of the different shells can be considered as dialects of the same language. Also, there are great similarities between them. All the explanations we provide here concern `bash` but for the most part, they are applicable to other shells.
The language of a shell mainly defines a grammatical rule. This rule describes the structure of a basic Unix command. The purpose of a Unix command is to trigger the execution of a program by indicating all the information necessary for its proper execution. We can take as a principle that for every program installed on a Unix machine there corresponds a command usable from the shell that bears the name of the program and that reciprocally, every Unix command is the name of a program installed on the computer. The set of Unix commands is therefore infinite, since when you install or write a new program, this in fact adds a new command to your Unix system. However, there is a set of commands installed by default on all Unix systems. We give you on page @section-commandes-unix a list of the main commands that you can use on all Unix computers you will use.
```{bash}
#| label: fig-basic-command
+#| eval: false
#| fig-cap: >
#| Basic structure of a Unix command line: a command line is divided into four main parts.
#| Only the first is mandatory, it indicates the program to use. The others allow defining
@@ -259,7 +345,7 @@ A Unix command line can be divided into four main parts (see Fig. @fig-basic-com
#### The Unix Command
-A Unix command is the name of a program installed on the machine. Thus, when you execute a Unix command like `ls` or `egrep`, you are actually launching the execution of a program of the same name installed on your computer. There is therefore somewhere stored in the hard disks of the latter a file that contains the code of the program to be executed. The question that then arises is: "How does the machine manage to find the file associated with a command when it is asked to interpret it?" It is obvious that if the computer had to search each time a Unix command is executed throughout its hard disks for the file to be executed, the search time would in most cases be longer than the program's calculation time. To allow a reasonable search time, program files are only searched for in a subset of the directories existing on the machine. This subset is described by a list of directories stored in an environment variable named `PATH`. It is possible to consult this list (see example @shell-path) or to modify it with the `setenv` command. The order of appearance of directories in this list plays a role if several programs exist with the same name in different directories in the list.
+A Unix command is the name of a program installed on the machine. Thus, when you execute a Unix command like `ls` or `egrep`, you are actually launching the execution of a program of the same name installed on your computer. There is therefore somewhere stored in the hard disks of the latter a file that contains the code of the program to be executed. The question that then arises is: "How does the machine manage to find the file associated with a command when it is asked to interpret it?" It is obvious that if the computer had to search each time a Unix command is executed throughout its hard disks for the file to be executed, the search time would in most cases be longer than the program's calculation time. To allow a reasonable search time, program files are only searched for in a subset of the directories existing on the machine. This subset is described by a list of directories stored in an environment variable named `PATH`. It is possible to consult this list (see example @shell-path) or to modify it with the `export` command. The order of appearance of directories in this list plays a role if several programs exist with the same name in different directories in the list.
```{bash}
#| label: shell-path
@@ -279,6 +365,7 @@ If you want to execute a program whose file is located in a directory not listed
```{bash}
#| label: shell-program
+#| eval: false
#| caption: >
#| Execute a program located in a non-standard directory: Suppose we have in our main directory
#| a directory named `myprograms` in which I store all my analysis programs. In this directory,
@@ -292,6 +379,7 @@ myprograms/myscript.csh turlututu
```{bash}
#| label: shell-program-courant
+#| eval: false
#| caption: >
#| Execute a program located in a non-standard directory: If the program is in the current
#| directory, it is necessary to add `./` before its name to specify its location.
@@ -307,6 +395,7 @@ Command options allow altering its operation by adjusting its parameters. Option
```{bash}
#| label: options-commande
+#| eval: false
#| caption: >
#| Options modify the behavior of a program: the `egrep` command filters a text file to only
#| let through the lines of it containing an instance of the searched pattern (`Root` in our
@@ -320,10 +409,20 @@ egrep -i Root /etc/passwd
egrep --ignore-case Root /etc/passwd
```
+```{bash}
+#| echo: false
+#| output: asis
+echo "root:x:0:0:root:/root:/bin/bash"
+echo "# (no output for second command)"
+echo "root:x:0:0:root:/root:/bin/bash"
+echo "root:x:0:0:root:/root:/bin/bash"
+```
+
Some options require arguments, for example the `-B` or `--before-context` option of the `egrep` command allows indicating how many lines located before a line normally printed by an `egrep` command should also be printed. These options therefore require an argument specifying the number of lines to add (see example @options-with-arguments). When using the short form of the option (`-B`), it is sufficient to add this number following the option, separated or not by a space: `-B 9` or `-B9`. If you use the long form, the argument is associated with its option by the sign "=": `--before-context=9`.
```{bash}
#| label: options-with-arguments
+#| eval: false
#| caption: >
#| Options can require arguments: The `-B` and `--before-context` options require as an argument
#| the number of lines of the filtered text that should be added before each of the lines that
@@ -333,10 +432,24 @@ grep -B 2 root /etc/passwd
grep --before-context=1 root /etc/passwd
```
+```
+ames:x:5:60:games:/usr/games:/usr/sbin/nologin
+man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
+lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
+mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
+news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
+uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
+proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
+www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
+backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
+list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
+```
+
It is frequent when using several options of a program in their short form to group their names behind a single "-" sign (see example @options-concat). If one of these options requires an argument, it is mandatory to place it in last position so that the argument can be added after it. If several options require arguments, it will not be possible to concatenate them into a single group. This possibility of grouping options makes it possible to simplify the writing of options but is absolutely not mandatory. It is not possible with options in their long form.
```{bash}
#| label: options-concat
+#| eval: false
#| caption: >
#| Short options can be concatenated: When several short options are used, their names can
#| be concatenated behind a single "-" sign. If one of them requires an argument, it must be
@@ -345,6 +458,19 @@ It is frequent when using several options of a program in their short form to gr
grep -iB 2 Root /etc/passwd
```
+```
+games:x:5:60:games:/usr/games:/usr/sbin/nologin
+man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
+lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
+mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
+news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
+uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
+proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
+www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
+backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
+list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
+```
+
The order of appearance of arguments in a Unix command line is normally unimportant. If the order of options influences the behavior of the program, this will be specified in its manual.
#### Command Arguments
@@ -372,6 +498,7 @@ Each word in a Unix command line using one of these characters will be replaced
```{bash}
#| label: cmd-bash
+#| eval: false
#| caption: Examples of using filenames with ambiguities.
ls -l
@@ -383,6 +510,16 @@ echo /[AD]*
echo /[uv]??
```
+```
+file1.txt file2.txt myprograms/
+# (no *foo files)
+bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
+# (no /mach* files)
+# (no /*.* files)
+# (no /[AD]* files)
+# (no /[uv]?? files)
+```
+
These filenames with ambiguities are most often used with file manipulation commands such as copy (`cp` command page @unix-cp), deletion (`rm` command page @unix-rm), or the `ls` command (page @unix-ls) allowing to obtain a list of files. They are also frequently used in loops that allow launching the same Unix command on a whole series of data sets.
### Redirection of Standard Inputs-Outputs
@@ -398,6 +535,7 @@ Each of these streams has one of its ends connected to the process to allow it t
```{bash}
#| label: fig-shell-inoutput
+#| eval: false
#| fig-cap: Setting the standard inputs and outputs of the shell.
```
@@ -413,6 +551,7 @@ In example @stdout, the `ls` command is executed a first time in a classic way,
```{bash}
#| label: stdout
+#| eval: false
#| caption: Redirection of standard output.
ls /
@@ -421,6 +560,31 @@ ls -l
cat my_listing
```
+```
+bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
+# (redirected to file)
+total
+-rw-r--r-- 1 user users 123 Jan 15 10:35 my_listing
+bin
+boot
+dev
+etc
+home
+lib
+media
+mnt
+opt
+proc
+root
+run
+sbin
+srv
+sys
+tmp
+usr
+var
+```
+
In this case, the connection diagram of the standard inputs and outputs of the process executing the `ls` program is presented in Figure @fig-ls-stdout. Only the standard output *stdout* is redirected. The error output remains connected to the terminal, which will therefore continue to retransmit any error messages generated.
If the file `my_listing` does not exist, it is created and filled with the results of the command. If this file already exists, the existing file is deleted and a new file with the same name is substituted for it. You must therefore be careful: this redirection mechanism very easily allows deleting a file containing other results.
@@ -429,6 +593,7 @@ If you want to add the results generated by our program to the end of an already
```{bash}
#| label: fig-ls-stdout
+#| eval: false
#| fig-cap: Redirection of the standard output of an `ls` command.
```
@@ -440,6 +605,7 @@ The redirection of standard input is materialized in the redirection part of a c
```{bash}
#| label: stdin
+#| eval: false
#| caption: Redirection of standard input and standard output.
egrep or < my_listing
@@ -447,6 +613,14 @@ egrep or < my_listing > my_selection
cat my_selection
```
+```
+proc
+sbin"
+echo "# (redirected to file)"
+echo "proc
+sbin
+```
+
The `egrep` command selects among the lines of text it receives on its standard input those containing a certain pattern (`or` in the case of example @stdin) to copy them to its standard output. To indicate to the process executing the `egrep` program that it should read the text to be analyzed from the file `my_listing`, it is sufficient to redirect its standard input *stdin*. Simultaneously with this redirection, it is also possible to redirect the standard output to a new file: `my_selection` in our example.
#### Redirection of Standard Output to Another Process
@@ -457,6 +631,7 @@ From a syntactic point of view, the language of a shell allows achieving this ef
```{bash}
#| label: fig-commande-tube
+#| eval: false
#| fig-cap: Structure of a double command.
```
@@ -464,6 +639,7 @@ It should be noted that commands upstream of a pipe cannot redirect their standa
```{bash}
#| label: pipe
+#| eval: false
#| caption: Construction of a complex command with a pipe.
ls / | grep or
@@ -471,10 +647,19 @@ ls / | grep or > my_selection
cat my_selection
```
+```
+proc
+sbin
+# (redirected to file)"
+proc
+sbin
+```
+
In a complex command like the one presented in example @pipe, a process is created for each of the commands and it is just the data that flows from one process to the other (see Figure @fig-ls-egrep-pipe).
```{bash}
#| label: fig-ls-egrep-pipe
+#| eval: false
#| fig-cap: Construction of a pipe between two processes.
```
@@ -486,29 +671,38 @@ The interest of a computer lies in its ability to automatically perform repetiti
Working automatically and repetitively requires using variables to store useful information that changes at each iteration. For example, if your Unix command must execute by reading its data in different files from one execution to another, you can no longer write the file name in your command since it will not always be the same.
-You already know the environment variables that are set by the `setenv` command and that serve to store information relating to the configuration of your system. There are simple variables that allow you to store for the duration of your Unix session all the information you deem necessary. They are set by the `set` command. To retrieve the value contained in a variable, simply precede its name with the "$" character (see example @variable).
+You already know the environment variables that are set by the `export` command and that serve to store information relating to the configuration of your system. There are simple variables that allow you to store for the duration of your Unix session all the information you deem necessary. They are set by simple assignment. To retrieve the value contained in a variable, simply precede its name with the "$" character (see example @variable).
```{bash}
#| label: variable
#| caption: Setting and displaying a variable.
-set myvariable="hello world"
+myvariable="hello world"
echo myvariable
echo $myvariable
```
-#### The `foreach` Loop
+#### The `for` Loop
-For our problem, repeating the same Unix command several times by making it work on different data files, we are going to create a variable that will take in turn as value each of the elements of a list. In our case, this list will be a list of file names and it will be built using the ambiguity characters on file names presented on page @fichier-star. To build such a variable whose value changes automatically, you must not use the `set` command, but the `foreach` command. All Unix commands inserted between the `foreach` command and its associated keyword `end` are executed once for each value taken by the variable.
+For our problem, repeating the same Unix command several times by making it work on different data files, we are going to create a variable that will take in turn as value each of the elements of a list. In our case, this list will be a list of file names and it will be built using the ambiguity characters on file names presented on page @fichier-star. To build such a variable whose value changes automatically, you must use the `for` command. All Unix commands inserted between the `for` command and its associated keyword `done` are executed once for each value taken by the variable.
```{bash}
#| label: boucle1
-#| caption: Construction of a `foreach` loop.
+#| eval: false
+#| caption: Construction of a `for` loop.
echo /[mnop]*
-foreach f ( /[mnop]* )
- echo I am working with file $f
-end
+for f in /[mnop]*; do
+ echo "I am working with file $f"
+done
+```
+
+```
+media mnt opt proc"
+I am working with file media
+I am working with file mnt
+I am working with file opt
+I am working with file proc
```
## Some Essential Unix Commands in Alphabetical Order
@@ -556,14 +750,13 @@ The `bash` command allows launching the execution of a new `bash` shell that wil
#### Example of Use
```{bash}
-#| label: cmd-bash
+#| label: cmd-bash-2
+#| eval: false
#| caption: Launch a `bash` shell.
-setenv foo
-export foo
+export foo=bar
bash
-setenv foo
-export foo
+export foo=baz
exit
```
@@ -588,6 +781,7 @@ bg [%job]
```{bash}
#| label: cmd-bg
+#| eval: false
#| caption: Sending a job to the background. The `sleep` command does nothing except wait for the indicated number of seconds. `^Z` symbolizes pressing the `Ctrl+z` keys.
sleep 30
@@ -636,6 +830,7 @@ cd [directory_name]
```{bash}
#| label: cmd-cd
+#| eval: false
#| caption: Changing directory.
pwd
@@ -693,9 +888,10 @@ chsh -s new_shell
```{bash}
#| label: cmd-chsh
+#| eval: false
#| caption: Changing shell.
-chsh -s /bin/tcsh
+chsh -s /bin/bash
```
### `cp`: Copy Files
@@ -765,7 +961,7 @@ env [name=value ...] [command [argument ...]]
#| label: cmd-env
#| caption: Configuring your execution environment.
-setenv hello "hello friends"
+export hello="hello friends"
env
env hello="goodbye" env
```
@@ -1080,15 +1276,15 @@ sed [-E] program [file ...]
| `program` | A character string describing in the `sed` language the program to execute to transform the text. |
| `data_file` | The file containing the text to transform. If this argument is absent, the standard input is taken as the data source. |
-### `setenv`: Set Environment Variable
-{#unix-setenv}
+### `export`: Set Environment Variable
+{#unix-export}
-Creates or modifies an environment variable. This command is specific to `tcsh`. A roundabout but simple way to check that our shell is indeed `tcsh` is to execute this command.
+Creates or modifies an environment variable. This command is specific to `bash`.
#### Prototype
```bash
-setenv [variable] [value]
+export [variable]=[value]
```
### `sort`: Sort Lines of a File
diff --git a/web_src/lectures/computers/unix/ls-stdout.svg b/web_src/lectures/computers/unix/ls-stdout.svg
new file mode 100644
index 0000000..79d3e4f
--- /dev/null
+++ b/web_src/lectures/computers/unix/ls-stdout.svg
@@ -0,0 +1,320 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/pipe.svg b/web_src/lectures/computers/unix/pipe.svg
new file mode 100644
index 0000000..83f5ce5
--- /dev/null
+++ b/web_src/lectures/computers/unix/pipe.svg
@@ -0,0 +1,495 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/process.svg b/web_src/lectures/computers/unix/process.svg
new file mode 100644
index 0000000..19f2e6c
--- /dev/null
+++ b/web_src/lectures/computers/unix/process.svg
@@ -0,0 +1,116 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/shell-inout.svg b/web_src/lectures/computers/unix/shell-inout.svg
new file mode 100644
index 0000000..b88c076
--- /dev/null
+++ b/web_src/lectures/computers/unix/shell-inout.svg
@@ -0,0 +1,294 @@
+
+
+
diff --git a/web_src/lectures/computers/unix/slides_unix.qmd b/web_src/lectures/computers/unix/slides_unix.qmd
new file mode 100644
index 0000000..c02c250
--- /dev/null
+++ b/web_src/lectures/computers/unix/slides_unix.qmd
@@ -0,0 +1,365 @@
+---
+title: "Unix Basics"
+format:
+ revealjs:
+ theme: beige
+ transition: fade
+ width: 1280
+ height: 720
+ center: true
+---
+
+## Why Learn Unix?
+
+- Foundational philosophy for modern computing
+- Powers most of the digital world
+- Born at AT&T's Bell Labs in late 1960s
+- Design principles: simplicity, modularity
+
+## Unix Today
+
+- **Certified Unix**: macOS
+- **Unix-like Systems**: GNU/Linux, BSD variants
+- **Linux**: Dominant Unix-like OS
+- Understanding Unix = understanding DNA of modern OS
+
+## Unix System Overview
+
+**Multi-user, Multitasking Operating System**
+
+```{mermaid}
+graph TD
+ A[OS Kernel] --> B[User 1 Process]
+ A --> C[User 2 Process]
+ A --> D[User 3 Process]
+ B --> E[File System]
+ C --> E
+ D --> E
+ style A fill:#2e86ab,color:#fff
+ style B fill:#a23b72,color:#fff
+ style C fill:#f18f01,color:#fff
+ style D fill:#c73e1d,color:#fff
+ style E fill:#3c8d5f,color:#fff
+```
+
+## File System Structure
+
+**Hierarchical Tree Organization**
+
+```{mermaid}
+graph TD
+ Root[/] --> etc["/etc config files"]
+ Root --> home["/home user directories"]
+ Root --> usr["/usr system software"]
+ Root --> var["/var variable data"]
+ home --> user1[/user1/]
+ home --> user2[/user2/]
+ user1 --> docs[Documents]
+ user1 --> downloads[Downloads]
+
+ style Root fill:#2e86ab,color:#fff;
+ style etc fill:#a23b72,color:#fff;
+ style home fill:#f18f01,color:#fff;
+ style usr fill:#c73e1d,color:#fff;
+ style var fill:#3c8d5f,color:#fff;
+```
+
+## File Naming Rules
+
+**Allowed Characters:**
+
+- Letters (a-z, A-Z), Numbers (0-9)
+- Recommended: `.`, `%`, `-`, `_`, `:`, `=`
+
+**Key Rules:**
+
+- **Case sensitive**: `File.txt` ≠ `file.txt` ≠ `FILE.TXT`
+- **No leading dash**: `-file` causes issues (use `./-file`)
+- **Hidden files**: Start with `.` (e.g., `.bashrc`)
+
+**Best Practices:**
+
+```bash
+good_file.txt # Clear and safe
+data-set-01.csv # Descriptive with hyphens
+project_config # No extension needed
+```
+
+## Globbing - Pattern Matching
+
+**Wildcard Characters:**
+
+```bash
+* # Any sequence of characters
+? # Any single character
+[abc] # Any character in set
+[a-z] # Any character in range
+```
+
+**Practical Examples:**
+
+```bash
+ls *.txt # All text files
+ls report?.pdf # report1.pdf, reportA.pdf
+ls [abc]*.log # a.log, b_data.log, c-backup.log
+ls image[0-9].jpg # image0.jpg through image9.jpg
+```
+
+## Advanced Globbing
+
+**Combining Patterns:**
+
+```bash
+ls *.{txt,md} # All .txt AND .md files
+ls project_{dev,prod} # project_dev, project_prod
+ls file[!0-9]* # Files NOT starting with digit
+```
+
+**Use in Commands:**
+
+```bash
+cp *.txt backup/ # Copy all text files
+rm temp_*.log # Remove temporary logs
+chmod +x *.sh # Make all scripts executable
+```
+
+**Pattern Expansion:**
+
+```bash
+echo *.py # Shows what patterns match
+ls data_202{3,4}*.csv # Multiple year patterns
+```
+
+## Globbing vs Regular Expressions
+
+**Key Differences:**
+
+- **Globbing**: File matching (`ls *.txt`)
+- **Regex**: Text pattern matching (`grep "^A" file.txt`)
+
+**Remember:** Globbing happens **before** command execution!
+
+## File Permissions
+
+**Three categories × Three rights**
+
+```bash
+-rwxr-xr-- # Owner: read, write, execute
+ # Group: read, execute
+ # Others: read only
+```
+
+```{=html}
+
+```
+
+## Process Concept
+
+**Program vs Process**
+
+```{=html}
+
+```
+
+## Shell Environment
+
+**Your Command Interface**
+
+```{=html}
+
+```
+
+## Command Structure
+
+```bash
+command [options] [arguments] [redirections]
+```
+
+**Examples:**
+```bash
+ls -l /home # List with details
+grep "error" log.txt # Search pattern
+find . -name "*.txt" # Find files
+```
+
+## Input/Output Redirection
+
+**Controlling Data Flow**
+
+```{mermaid}
+flowchart LR
+ A[Input File data.txt] --> B{Command program}
+ B --> C[Output File results.txt]
+
+ style A fill:#2e86ab,color:#fff
+ style B fill:#a23b72,color:#fff
+ style C fill:#f18f01,color:#fff
+```
+
+## Pipes - Command Chaining
+
+**Connect processes together**
+
+```bash
+cat file.txt | grep "error" | sort | uniq
+```
+
+```{mermaid}
+flowchart LR
+ A[cat Reads file] -->|stdout| B[grep Filters text]
+ B -->|stdout| C[sort Orders data]
+ C -->|stdout| D[uniq Removes duplicates]
+
+ style A fill:#2e86ab,color:#fff
+ style B fill:#a23b72,color:#fff
+ style C fill:#f18f01,color:#fff
+ style D fill:#3c8d5f,color:#fff
+```
+
+## Essential Commands
+
+| Category | Commands | Purpose |
+|----------|----------|---------|
+| **Files** | `ls, cp, mv, rm, mkdir` | Manage files and directories |
+| **Navigation** | `cd, pwd` | Move around file system |
+| **Text** | `cat, grep, head, tail, wc` | View and search text |
+| **Process** | `ps, kill, &, bg, fg` | Manage running programs |
+| **Help** | `man, --help` | Get command information |
+
+## Getting Started
+
+**Next Steps:**
+- Practice basic file operations
+- Learn command combinations with pipes
+- Study pattern matching with wildcards
+- Explore shell scripting for automation
+- Use `man` pages for detailed help
+
+**Remember:** Unix mastery comes through practice!
diff --git a/web_src/lectures/computers/unix/unix-modern-bash.qmd b/web_src/lectures/computers/unix/unix-modern-bash.qmd
new file mode 100644
index 0000000..b036c55
--- /dev/null
+++ b/web_src/lectures/computers/unix/unix-modern-bash.qmd
@@ -0,0 +1,484 @@
+---
+title: "Unix Essentials — Modern Bash Edition"
+subtitle: "A practical, color‑blind‑friendly introduction"
+author: "Your Name"
+format:
+ html:
+ toc: true
+ toc-depth: 3
+ code-tools: true
+ code-fold: false
+ theme: cosmo
+ smooth-scroll: true
+ include-in-header:
+ text: |
+
+execute:
+ echo: true
+ warning: false
+ message: false
+mermaid:
+ theme: neutral
+ background: transparent
+ width: 100%
+page-layout: article
+---
+
+# Introduction to Unix
+
+Unix is a family of operating systems and a set of design ideas—small programs that do one thing well, text as a universal interface, and easy composition through pipes. Those ideas power Linux servers, macOS, iOS, Android (via Linux), and most cloud infrastructure today. Learning Unix is learning the lingua franca of modern computing.
+
+## Certified UNIX vs. Unix‑like
+
+“UNIX” is a trademark of The Open Group for systems that pass the POSIX/SUS conformance tests. macOS is certified; Linux distributions and BSDs are “Unix‑like”—they follow the same model and standards. For our purposes, you can treat them similarly.
+
+> This course uses **bash** exclusively. Commands and syntax target modern GNU/*BSD/macOS shells and core utilities. When an option is GNU‑specific, we’ll note it.
+
+# Users and Accounts
+
+Each person has a **user account** (username/login) with a numeric **UID**, a **primary group**, a **home directory**, and a **default shell**. User account metadata lives in `/etc/passwd` (user list) and `/etc/shadow` (password hashes, not world‑readable).
+
+```{bash}
+#| label: ex-passwd-head
+#| eval: false
+#| caption: Inspecting the user database (first lines of /etc/passwd).
+head -15 /etc/passwd
+```
+
+# The Unix File System
+
+The filesystem is a single rooted hierarchy (`/`). Directories are nodes; files are leaves; symbolic links add extra edges (making it a DAG).
+
+{style="display:block;margin:0;padding:0;" fig-cap="A simplified Unix filesystem tree. The highlighted path resolves to `/etc/passwd`." #fig-fs-unix}
+
+Common top‑level directories:
+
+- `/etc` – system configuration
+- `/var` – variable state (logs, spool, caches)
+- `/bin`, `/usr/bin` – essential and additional executables
+- `/usr`, `/usr/local` – the main system and locally installed software
+- `/home` (or `/Users` on macOS) – user homes
+
+## Filenames and Rules
+
+- Case matters: `Foo.txt` ≠ `foo.txt`.
+- Avoid spaces and exotic punctuation in names; prefer letters, digits, `. - _`.
+- Names starting with `.` are “hidden” (e.g., `~/.bashrc`).
+
+## Links
+
+Two kinds of links:
+
+- **Hard link**: an additional directory entry pointing to the same inode (same file). Cannot span filesystems; not for directories (with rare admin exceptions).
+- **Symbolic link**: a small file that points to a path (can cross filesystems).
+
+{fig-cap="Symbolic link creates an extra path to the same target." #fig-fs-link}
+
+## `.` and `..`
+
+Every directory contains entries `.` (itself) and `..` (parent). They make relative navigation and scripting concise.
+
+{fig-cap="Special entries `.` and `..` help navigate without absolute paths." #fig-fs-spdir}
+
+## Current Working Directory and Relative Paths
+
+Your **current working directory** (CWD) is where relative paths are resolved. Use `pwd` to show it and `cd` to change it.
+
+```{bash}
+#| eval: false
+pwd
+cd /usr
+pwd
+cd - # jump back
+```
+
+## Permissions (Mode), Ownership, and Umask
+
+Each file has an **owner** (user), a **group**, and three permission triplets (r,w,x) for **user**, **group**, and **others**:
+
+```{bash}
+#| eval: false
+# long listing shows mode, owner, group, size, date, name
+ls -l /bin/bash
+# change permissions: add user execute, remove group write
+chmod u+x,g-w script.sh
+# change owner/group (requires privileges)
+sudo chown alice:science data.tsv
+# show and set default creation mask
+umask # e.g., 0022
+umask 0002 # collaborative group-writable defaults
+```
+
+# Processes
+
+A **program** is code on disk; a **process** is a running instance with its own memory, environment, and open file descriptors. Each process has a **PID** and a **PPID** (parent PID).
+
+```{bash}
+#| eval: false
+ps aux | head -5
+pstree -a | head -20 # on macOS: brew install pstree; or use 'pgrep -lf .'
+```
+
+## The Process “Anatomy”
+
+- **Code** (the program image)
+- **Data/Heap/Stack**
+- **Environment** (variables like `PATH`, `HOME`)
+- **Standard streams**: `stdin` (0), `stdout` (1), `stderr` (2)
+
+{fig-cap="A process has code, data, environment, and standard streams." #fig-process-anatomy}
+
+## Lifecycle and Inheritance
+
+Processes are created by **fork/exec**. Children inherit the parent’s environment and open descriptors unless changed. When a child exits, it becomes a **zombie** until the parent reaps it.
+
+```{mermaid}
+%%| echo: false
+%%| code-fold: false
+graph TD
+A["Parent process"] -->|fork| B["Child (COW)"]
+B -->|exec| C["New program image"]
+C -->|exit| D{Parent waits}
+D -- yes --> E["Child reaped"]
+D -- no --> F["Zombie until parent waits"]
+```
+
+# The Shell (bash)
+
+The shell is a command interpreter and a scripting language. We’ll use **bash** only.
+
+## Structure of a Command Line
+
+```text
+command [OPTIONS...] [ARGUMENTS...] [REDIRECTIONS/PIPES]
+```
+
+- **Command**: executable name or path
+- **Options**: short `-l` or long `--long`
+- **Arguments**: files, patterns, values
+- **Redirections/Pipes**: `>`, `>>`, `<`, `2>`, `|`, `|&`, `<<<`
+
+```{bash}
+#| label: ex-path
+#| caption: PATH lists directories searched for commands, left to right.
+echo "$PATH"
+command -v bash # show full path to the executable bash will run
+```
+
+If a program isn’t on `PATH`, run it via a path (absolute or relative):
+
+```{bash}
+#| eval: false
+./mytool --help
+/home/alice/bin/mytool --version
+```
+
+## Modern Note on `grep`
+
+`egrep` and `fgrep` are deprecated. Use `grep -E` (extended regex) and `grep -F` (fixed strings).
+
+```{bash}
+#| eval: false
+grep -E 'root|daemon' /etc/passwd
+grep -Fi 'error' /var/log/system.log
+```
+
+# Globs (Filename Patterns)
+
+The shell expands patterns **before** running the command:
+
+| Pattern | Meaning |
+|---|---|
+| `*` | any string (including empty) |
+| `?` | any single char |
+| `[abc]` | any of listed chars |
+| `{a,b,c}` | brace expansion (not a glob; bash feature) |
+
+```{bash}
+#| eval: false
+echo *.txt
+ls -ld /[uv]??
+printf '%s\n' project/{data,docs,src}
+```
+
+# Redirection and Pipes
+
+Standard streams: `stdin` (0), `stdout` (1), `stderr` (2).
+
+{fig-cap="Default streams: keyboard → stdin; stdout/stderr → terminal." #fig-shell-inoutput}
+
+## Redirect to/From Files
+
+```{bash}
+#| eval: false
+ls / > listing.txt # stdout to file (overwrite)
+ls / >> listing.txt # append
+grep -E 'log' < listing.txt # stdin from file
+grep -E 'log' listing.txt > matches.txt 2> errors.log
+```
+
+## Pipelines
+
+`|` connects stdout of left command to stdin of right command. Use `|&` to pipe both stdout and stderr (bash).
+
+{fig-cap="A two‑stage pipeline: stdout of cmd1 becomes stdin of cmd2." #fig-commande-tube}
+
+```{bash}
+#| eval: false
+ls -l /usr/bin | head -n 5
+journalctl -u ssh |& grep -Ei 'fail|error' # GNU/Linux
+```
+
+{fig-cap="Redirecting `ls` output into a file." #fig-ls-stdout}
+{fig-cap="Regular file."}
+{fig-cap="Directory."}
+{fig-cap="Home directory icon."}
+{fig-cap="Regular file (again, for legend grouping)."}
+{fig-cap="Symbolic link (legend)."}
+
+# Loops, Variables, and Scripting
+
+## Variables
+
+Create with `name=value`. Read with `$name`. Export to children with `export name`.
+
+```{bash}
+#| label: ex-vars
+greeting="hello world"
+echo "$greeting"
+export PATH="$HOME/bin:$PATH"
+```
+
+## `for` Loops
+
+```{bash}
+#| eval: false
+for f in /var/log/*.log; do
+ echo "Checking: $f"
+ grep -Eci 'error|warning' "$f"
+done
+```
+
+## Safer Bash
+
+- Always quote expansions: `"$var"`
+- Enable strict mode in scripts:
+ ```bash
+ set -Eeuo pipefail
+ IFS=$'\n\t'
+ ```
+- Prefer `mktemp` for temp files
+- Use `printf` instead of `echo` for exact output
+
+## Color‑Blind‑Friendly Tips
+
+Use **shapes**, **labels**, and **line styles** rather than relying solely on color in outputs and diagrams. In Mermaid use dashed/solid edges and different node shapes:
+
+```{mermaid}
+%%| echo: false
+%%| code-fold: false
+flowchart LR
+ classDef solid stroke-width:2;
+ classDef dashed stroke-dasharray: 5 5, stroke-width:2;
+ A([File]):::solid --> B{{Grep}}:::dashed
+ B --> C[[Matches]]
+```
+
+# Essential Commands (Modernized, Bash‑centric)
+
+Below are concise prototypes. Use `--help` and `man` for details.
+
+## `awk` — Pattern scanning and processing
+
+```bash
+awk [-F SEP] 'PROGRAM' [FILE...]
+```
+
+- `-F` field separator. Example: `awk -F: '{print $1,$3}' /etc/passwd`
+
+## `bash` — The shell
+
+```bash
+bash # start a new interactive shell
+bash script.sh # run a script
+```
+
+## `bg` / `fg` / `jobs` — Job control
+
+```bash
+sleep 60 & # run in background
+jobs # list jobs
+fg %1 # bring job 1 to foreground
+bg %1 # resume job 1 in background
+```
+
+## `cat` — Concatenate files
+
+```bash
+cat file1 [file2 ...] > out
+```
+
+## `cd` — Change directory
+
+```bash
+cd [DIR] # no arg: go to $HOME
+```
+
+## `chmod` — Change permissions
+
+```bash
+chmod [-R] MODE FILE...
+chmod u+rwx,g+rx,o-rwx FILE
+```
+
+## `chsh` — Change login shell
+
+```bash
+chsh -s /bin/bash
+```
+
+## `cp` — Copy files
+
+```bash
+cp [-R] SRC... DEST
+```
+
+## `diff` — Text diffs
+
+```bash
+diff -u old.txt new.txt | less
+```
+
+## `env` / `export` — Environment
+
+```bash
+env | sort
+export VAR=value
+```
+
+## `grep` — Search text (replaces `egrep`/`fgrep`)
+
+```bash
+grep [-E|-F] [-iR] PATTERN [FILE...]
+```
+
+## `head` / `tail` — File ends
+
+```bash
+head -n 20 FILE
+tail -n 50 FILE
+tail -f /var/log/syslog # follow
+```
+
+## `join` — Join lines on a field
+
+```bash
+join -1 1 -2 1 file1 file2
+```
+
+## `kill` — Send signals
+
+```bash
+kill -SIGTERM PID
+kill -9 PID # last resort
+kill -l # list signals
+```
+
+## `ln` — Create links
+
+```bash
+ln FILE LINKNAME # hard link
+ln -s TARGET LINKNAME # symlink
+```
+
+## `ls` — List files
+
+```bash
+ls -la
+ls -ltrh /var/log
+```
+
+## `man` — Manuals
+
+```bash
+man ls
+man -k network # search by keyword
+```
+
+## `mkdir` — Make directories
+
+```bash
+mkdir -p project/{data,docs,src}
+```
+
+## `mv` — Move/rename
+
+```bash
+mv old new
+mv file*.txt dir/
+```
+
+## `paste` — Merge lines side by side
+
+```bash
+paste file1 file2
+```
+
+## `ps` — Process status
+
+```bash
+ps aux | grep -E '[n]ginx'
+ps -U "$USER" -o pid,ppid,stat,cmd
+```
+
+## `pwd` — Current directory
+
+```bash
+pwd
+```
+
+## `rm` — Remove files (dangerous)
+
+```bash
+rm [-rf] PATH...
+```
+
+> Tip: Use `trash`/`gio trash` on desktops when possible.
+
+## `sed` — Stream editor
+
+```bash
+sed -E 's/old/new/g' FILE
+```
+
+## `sort` / `uniq` — Sorting and deduping
+
+```bash
+sort -u names.txt
+sort -k2,2n data.tsv | uniq -c
+```
+
+## `wc` — Counts
+
+```bash
+wc -lwc FILE
+```
+
+# Practice: Putting It Together
+
+```{bash}
+#| eval: false
+# Find the 10 most common failed SSH sources today (GNU/Linux example)
+journalctl -u ssh --since today \
+| grep -Ei 'failed|authentication failure' \
+| awk '{print $(NF)}' \
+| sort | uniq -c | sort -k1,1nr | head -10
+```
+