From 4e6a880d4e4357e627b5ca2fe7f02b768830eb2b Mon Sep 17 00:00:00 2001 From: Minijackson Date: Thu, 6 Aug 2020 09:15:31 +0200 Subject: cli: init --- cli.md | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 cli.md diff --git a/cli.md b/cli.md new file mode 100644 index 0000000..07a3b73 --- /dev/null +++ b/cli.md @@ -0,0 +1,241 @@ +% The Linux command-line + + +## Purpose + +The main purpose of the command line is to execute other programs using a text +only interface. + +While "program" in a broader context might imply a user interface with +a separate window, buttons, etc., what I mean here is a program that only +outputs text for us to see. + +While the command-line was mostly created because historically, computers +weren't quite powerful[^teletypewriter], it is still used to this day by +a large amount of people for various reasons (some people find it handy, +clearer, faster, or even more elegant). + +[^teletypewriter]: + Another possible reason it was created is because computers didn't even + have screen before, but instead printed text on paper + +TODO: link teletypewriter video by Drew Devault + + +## Usage + +When you open a terminal, you will be greeted by a prompt that will kindly +"ask" you to input a command. + +A command is composed of a command name (or verb), and 0, 1, or more arguments. +The verb and each arguments are separated by 1 or more spaces. + +Just like in English grammar, the arguments have different meanings for +different verbs. For example, when you use the verb `cp` (for "copy"), the +first arguments are the "source" (i.e. the files to copy), and the last +argument is the destination: + +```bash +# Copies the file "file_1.txt" into "file_2.txt" +user@host:~$ cp file_1.txt file_2.txt +# ^^ ^^^^^^^^^^ ^^^^^^^^^^ +# | | | +# | '-------------'- arguments +# | +# '---------------------- command name (verb) +``` + +But when you use the verb `mkdir` (for "make directory"), all the arguments are +names of directories that you want to create: + +```bash +# Create the directories "dir_1", "dir_2", and "dir_3" +user@host:~$ mkdir dir_1 dir_2 dir_3 +``` + +For any new commands you learn, be sure to check the manual by executing the +command `man `. For example, if you want to know more about the +`mkdir` command, you simply have to execute: `man mkdir`. + + +## Argument conventions + +If you are developing a new command-line program, you are free to do anything +you want with the arguments that are passed down to you. + +Should you wish it, you could make a program that goes like this: + +```bash +# Copies the file "file_1.txt" into "file_2.txt" +user@host:~$ my_cp ~~file_1.txt//file_2.txt~~ + +# Copies the file "file_1.txt" into "file_2.txt" +# and overwrite "file_2.txt" if it exists +user@host:~$ my_cp ~~file_1.txt//file_2.txt~~ _~overwrite +``` + +But that would be pretty horrible. + +More than the fact that this syntax is really ugly to look at, we need a common +syntax to specify options, flags, etc. + +And this is where the POSIX convention, and the GNU convention comes in. + +It specifies that optional arguments are to be prefixed by `--`, or `-` if it +is just one letter: + +```bash +# Copies the file "file_1.txt" into "file_2.txt" +# and overwrite "file_2.txt" if it exists +user@host:~$ cp file_1.txt file_2.txt --force + +# Copies the file "file_1.txt" into "file_2.txt" +# and overwrite "file_2.txt" if it exists (using the short option) +user@host:~$ cp file_1.txt file_2.txt -f +``` + +Some options can also take themselves an argument, by separating them with a +`=`, or just using the following command-line argument: + +```bash +# Lists file in the current directory, sorted by size +user@host:~$ ls --sort=size + +# Same thing +user@host:~$ ls --sort size +``` + +TODO: we call options without argument a "flag" + +TODO: Remind that these are still convention, some programs don't respect that + +## Components + +While using the term "command-line" might suggest that it is composed of +a single component, it is not. Should you have a problem to debug, I always +find it useful to know how the different pieces interact with on another. + +So, here are the different pieces that are the most useful to us[^tty]: + +[^tty]: + Some components are omitted for simplicity's sake, like the concept of + "tty", "pty", and others + +The terminal / terminal emulator +: Renders text on the screen + +The prompt / REPL +: A part of the shell that interactively asks for command-lines, and shows you + some informations like what user you are logged as, what directory you're + currently in, etc. + +The shell +: Interprets command-lines and execute them + + +### The terminal + +As I said above, the terminal (or terminal emulator) is the program that +renders the text on the screen. It is therefore *not* the kind of program I was +talking about in the [purpose] section. + +It is a graphical program that creates a new window, runs a text-only program +as a child process, and for each character outputted by the text program, +convert the character into pixels that are rendered in the window for our eyes +to see. + +Therefore, if you want to change the font displayed, the terminal is the +program to configure. + +"But what kind of child program does the terminal starts?" you might ask. And +that brings us to: + +### The prompt + +While a terminal emulator is able to run any kind of program, it would be most +useful if it started a program that repeatedly would take a command-line and +execute it. + +It would be a pain to start a terminal emulator for each and every little +commands we wanted to execute[^close-on-exit]. + +[^close-on-exit]: + In fact it is so common to run a prompt in a terminal emulator that most + terminal just closes the window and exit when the text program exits. If + you were to run `mkdir new_dir` as the terminal command, you would see + a new window being created, and it would close after ~0.002 seconds. + +And this is why we run an interactive text program: it's just easier, faster, +and way less annoying. + +When you first start a terminal in a new installation of a Linux system, you +will mostly likely be greeted with a Bash prompt. Bash being the name of one of +the several shells that exists in this world. + +Your prompt will likely resemble this (annotations added): + + +```bash +# ,------ username you are logged in as +# | +# | ,---- directory you are in +# | | '~' means your user directory +# vvvv v + user@host:~$ +# ^^^^ ^ +# | | +# | '--- '$' if you are a normal user, +# | '#' if you are the root user +# | +# '--- name of the machine you are on + +``` + +But just like everything is in the UNIX world, everything about it is +customizable: + +- You can for example run a prompt from a different shell: instead of using the + Bash prompt, you can use the one from Zsh, Fish, Csh, etc. +- You can customize the prompt itself using the configuration system of Bash, + Zsh, etc. + +TODO: link doc of bash prompt + + +### The shell + +It might seem like the prompt is everything there is about Bash, Zsh, etc., but +these programs are actually much more powerful than that: a shell is +a full-size programming language! + +Like any programming language it is very useful for automating tasks, and the +fact that a shell script (a program written in a shell language) is included in +every Linux system, and that it is very quick to write makes it very common in +embedded systems and system administration. + +So, let's go over the particularities of the shell programming language. + +#### Basic interpretation of a command + +```c +#include + +/// The entry point of the program. +/// +/// \param argc the number of command line arguments +/// \param argv the command line argument, +/// as an array of NULL terminated strings +int main(int argc, char** argv) { + for(int i = 0; i < argc; ++i) { + printf("Argument %i: %s\n", i, argv[i]); + } +} +``` + +#### Variables and interpolation + +#### Control flow + +#### The various shell implementations + +## Further reading -- cgit v1.2.3