diff options
author | Minijackson <minijackson@riseup.net> | 2020-08-06 09:15:31 +0200 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2020-08-06 09:15:31 +0200 |
commit | 4e6a880d4e4357e627b5ca2fe7f02b768830eb2b (patch) | |
tree | a39a3672f5119a5c829e1cade8dad0f405737516 /cli.md | |
parent | a9574e12b91959bdb51226f82b97c82ca4e1a878 (diff) | |
download | wtf-is-linux-website-4e6a880d4e4357e627b5ca2fe7f02b768830eb2b.tar.gz wtf-is-linux-website-4e6a880d4e4357e627b5ca2fe7f02b768830eb2b.zip |
cli: init
Diffstat (limited to 'cli.md')
-rw-r--r-- | cli.md | 241 |
1 files changed, 241 insertions, 0 deletions
@@ -0,0 +1,241 @@ | |||
1 | % The Linux command-line | ||
2 | |||
3 | |||
4 | ## Purpose | ||
5 | |||
6 | The main purpose of the command line is to execute other programs using a text | ||
7 | only interface. | ||
8 | |||
9 | While "program" in a broader context might imply a user interface with | ||
10 | a separate window, buttons, etc., what I mean here is a program that only | ||
11 | outputs text for us to see. | ||
12 | |||
13 | While the command-line was mostly created because historically, computers | ||
14 | weren't quite powerful[^teletypewriter], it is still used to this day by | ||
15 | a large amount of people for various reasons (some people find it handy, | ||
16 | clearer, faster, or even more elegant). | ||
17 | |||
18 | [^teletypewriter]: | ||
19 | Another possible reason it was created is because computers didn't even | ||
20 | have screen before, but instead printed text on paper | ||
21 | |||
22 | TODO: link teletypewriter video by Drew Devault | ||
23 | |||
24 | |||
25 | ## Usage | ||
26 | |||
27 | When you open a terminal, you will be greeted by a prompt that will kindly | ||
28 | "ask" you to input a command. | ||
29 | |||
30 | A command is composed of a command name (or verb), and 0, 1, or more arguments. | ||
31 | The verb and each arguments are separated by 1 or more spaces. | ||
32 | |||
33 | Just like in English grammar, the arguments have different meanings for | ||
34 | different verbs. For example, when you use the verb `cp` (for "copy"), the | ||
35 | first arguments are the "source" (i.e. the files to copy), and the last | ||
36 | argument is the destination: | ||
37 | |||
38 | ```bash | ||
39 | # Copies the file "file_1.txt" into "file_2.txt" | ||
40 | user@host:~$ cp file_1.txt file_2.txt | ||
41 | # ^^ ^^^^^^^^^^ ^^^^^^^^^^ | ||
42 | # | | | | ||
43 | # | '-------------'- arguments | ||
44 | # | | ||
45 | # '---------------------- command name (verb) | ||
46 | ``` | ||
47 | |||
48 | But when you use the verb `mkdir` (for "make directory"), all the arguments are | ||
49 | names of directories that you want to create: | ||
50 | |||
51 | ```bash | ||
52 | # Create the directories "dir_1", "dir_2", and "dir_3" | ||
53 | user@host:~$ mkdir dir_1 dir_2 dir_3 | ||
54 | ``` | ||
55 | |||
56 | For any new commands you learn, be sure to check the manual by executing the | ||
57 | command `man <command>`. For example, if you want to know more about the | ||
58 | `mkdir` command, you simply have to execute: `man mkdir`. | ||
59 | |||
60 | |||
61 | ## Argument conventions | ||
62 | |||
63 | If you are developing a new command-line program, you are free to do anything | ||
64 | you want with the arguments that are passed down to you. | ||
65 | |||
66 | Should you wish it, you could make a program that goes like this: | ||
67 | |||
68 | ```bash | ||
69 | # Copies the file "file_1.txt" into "file_2.txt" | ||
70 | user@host:~$ my_cp ~~file_1.txt//file_2.txt~~ | ||
71 | |||
72 | # Copies the file "file_1.txt" into "file_2.txt" | ||
73 | # and overwrite "file_2.txt" if it exists | ||
74 | user@host:~$ my_cp ~~file_1.txt//file_2.txt~~ _~overwrite | ||
75 | ``` | ||
76 | |||
77 | But that would be pretty horrible. | ||
78 | |||
79 | More than the fact that this syntax is really ugly to look at, we need a common | ||
80 | syntax to specify options, flags, etc. | ||
81 | |||
82 | And this is where the POSIX convention, and the GNU convention comes in. | ||
83 | |||
84 | It specifies that optional arguments are to be prefixed by `--`, or `-` if it | ||
85 | is just one letter: | ||
86 | |||
87 | ```bash | ||
88 | # Copies the file "file_1.txt" into "file_2.txt" | ||
89 | # and overwrite "file_2.txt" if it exists | ||
90 | user@host:~$ cp file_1.txt file_2.txt --force | ||
91 | |||
92 | # Copies the file "file_1.txt" into "file_2.txt" | ||
93 | # and overwrite "file_2.txt" if it exists (using the short option) | ||
94 | user@host:~$ cp file_1.txt file_2.txt -f | ||
95 | ``` | ||
96 | |||
97 | Some options can also take themselves an argument, by separating them with a | ||
98 | `=`, or just using the following command-line argument: | ||
99 | |||
100 | ```bash | ||
101 | # Lists file in the current directory, sorted by size | ||
102 | user@host:~$ ls --sort=size | ||
103 | |||
104 | # Same thing | ||
105 | user@host:~$ ls --sort size | ||
106 | ``` | ||
107 | |||
108 | TODO: we call options without argument a "flag" | ||
109 | |||
110 | TODO: Remind that these are still convention, some programs don't respect that | ||
111 | |||
112 | ## Components | ||
113 | |||
114 | While using the term "command-line" might suggest that it is composed of | ||
115 | a single component, it is not. Should you have a problem to debug, I always | ||
116 | find it useful to know how the different pieces interact with on another. | ||
117 | |||
118 | So, here are the different pieces that are the most useful to us[^tty]: | ||
119 | |||
120 | [^tty]: | ||
121 | Some components are omitted for simplicity's sake, like the concept of | ||
122 | "tty", "pty", and others | ||
123 | |||
124 | The terminal / terminal emulator | ||
125 | : Renders text on the screen | ||
126 | |||
127 | The prompt / REPL | ||
128 | : A part of the shell that interactively asks for command-lines, and shows you | ||
129 | some informations like what user you are logged as, what directory you're | ||
130 | currently in, etc. | ||
131 | |||
132 | The shell | ||
133 | : Interprets command-lines and execute them | ||
134 | |||
135 | |||
136 | ### The terminal | ||
137 | |||
138 | As I said above, the terminal (or terminal emulator) is the program that | ||
139 | renders the text on the screen. It is therefore *not* the kind of program I was | ||
140 | talking about in the [purpose] section. | ||
141 | |||
142 | It is a graphical program that creates a new window, runs a text-only program | ||
143 | as a child process, and for each character outputted by the text program, | ||
144 | convert the character into pixels that are rendered in the window for our eyes | ||
145 | to see. | ||
146 | |||
147 | Therefore, if you want to change the font displayed, the terminal is the | ||
148 | program to configure. | ||
149 | |||
150 | "But what kind of child program does the terminal starts?" you might ask. And | ||
151 | that brings us to: | ||
152 | |||
153 | ### The prompt | ||
154 | |||
155 | While a terminal emulator is able to run any kind of program, it would be most | ||
156 | useful if it started a program that repeatedly would take a command-line and | ||
157 | execute it. | ||
158 | |||
159 | It would be a pain to start a terminal emulator for each and every little | ||
160 | commands we wanted to execute[^close-on-exit]. | ||
161 | |||
162 | [^close-on-exit]: | ||
163 | In fact it is so common to run a prompt in a terminal emulator that most | ||
164 | terminal just closes the window and exit when the text program exits. If | ||
165 | you were to run `mkdir new_dir` as the terminal command, you would see | ||
166 | a new window being created, and it would close after ~0.002 seconds. | ||
167 | |||
168 | And this is why we run an interactive text program: it's just easier, faster, | ||
169 | and way less annoying. | ||
170 | |||
171 | When you first start a terminal in a new installation of a Linux system, you | ||
172 | will mostly likely be greeted with a Bash prompt. Bash being the name of one of | ||
173 | the several shells that exists in this world. | ||
174 | |||
175 | Your prompt will likely resemble this (annotations added): | ||
176 | |||
177 | |||
178 | ```bash | ||
179 | # ,------ username you are logged in as | ||
180 | # | | ||
181 | # | ,---- directory you are in | ||
182 | # | | '~' means your user directory | ||
183 | # vvvv v | ||
184 | user@host:~$ | ||
185 | # ^^^^ ^ | ||
186 | # | | | ||
187 | # | '--- '$' if you are a normal user, | ||
188 | # | '#' if you are the root user | ||
189 | # | | ||
190 | # '--- name of the machine you are on | ||
191 | |||
192 | ``` | ||
193 | |||
194 | But just like everything is in the UNIX world, everything about it is | ||
195 | customizable: | ||
196 | |||
197 | - You can for example run a prompt from a different shell: instead of using the | ||
198 | Bash prompt, you can use the one from Zsh, Fish, Csh, etc. | ||
199 | - You can customize the prompt itself using the configuration system of Bash, | ||
200 | Zsh, etc. | ||
201 | |||
202 | TODO: link doc of bash prompt | ||
203 | |||
204 | |||
205 | ### The shell | ||
206 | |||
207 | It might seem like the prompt is everything there is about Bash, Zsh, etc., but | ||
208 | these programs are actually much more powerful than that: a shell is | ||
209 | a full-size programming language! | ||
210 | |||
211 | Like any programming language it is very useful for automating tasks, and the | ||
212 | fact that a shell script (a program written in a shell language) is included in | ||
213 | every Linux system, and that it is very quick to write makes it very common in | ||
214 | embedded systems and system administration. | ||
215 | |||
216 | So, let's go over the particularities of the shell programming language. | ||
217 | |||
218 | #### Basic interpretation of a command | ||
219 | |||
220 | ```c | ||
221 | #include <stdio.h> | ||
222 | |||
223 | /// The entry point of the program. | ||
224 | /// | ||
225 | /// \param argc the number of command line arguments | ||
226 | /// \param argv the command line argument, | ||
227 | /// as an array of NULL terminated strings | ||
228 | int main(int argc, char** argv) { | ||
229 | for(int i = 0; i < argc; ++i) { | ||
230 | printf("Argument %i: %s\n", i, argv[i]); | ||
231 | } | ||
232 | } | ||
233 | ``` | ||
234 | |||
235 | #### Variables and interpolation | ||
236 | |||
237 | #### Control flow | ||
238 | |||
239 | #### The various shell implementations | ||
240 | |||
241 | ## Further reading | ||