-
Notifications
You must be signed in to change notification settings - Fork 0
/
tutorial-1.tex
1031 lines (782 loc) · 44.7 KB
/
tutorial-1.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[12pt]{article}
%\usepackage[portuguese]{babel}
\usepackage{natbib}
\usepackage{url}
\usepackage[utf8x]{inputenc}
\usepackage{amsmath}
\usepackage{graphicx}
\graphicspath{{images/}}
\usepackage{parskip}
\usepackage{fancyhdr}
\usepackage{vmargin}
\setmarginsrb{1.5 cm}{2.5 cm}{1.5 cm}{2.5 cm}{1 cm}{1.5 cm}{1 cm}{1.5 cm}
\usepackage{hyperref}
\hypersetup{
colorlinks=true,
citecolor=black,
filecolor=black,
linkcolor=black,
urlcolor=black
}
\let\oldhref\href
\renewcommand{\href}[2]{\oldhref{#1}{\bfseries#2}}
\usepackage[bottom]{footmisc}
\usepackage{caption}
\DeclareCaptionFormat{sanslabel}{#3}%
\usepackage[section]{placeins}
\usepackage{xcolor}
\definecolor{light-gray}{gray}{0.95}
\usepackage{listings}
\lstset{basicstyle=\ttfamily,
showstringspaces=false,
commentstyle=\color{red},
keywordstyle=\color{blue},
backgroundcolor=\color{light-gray},
breaklines=true,
extendedchars=true,
literate={é}{{\'e}}1
}
\lstset{aboveskip=15pt,belowskip=15pt}
\usepackage[autostyle]{csquotes}
\def\labelitemi{--}
\usepackage{enumitem}
\setlist{nosep}
\usepackage{booktabs}
\usepackage[T1]{fontenc} % use \textless
\usepackage{tikz} % super package for complex and awesome drawing
\title{Tutorial} % Title
%\author{} % Author
\date{\today} % Date
\makeatletter
\let\thetitle\@title
%\let\theauthor\@author
\let\thedate\@date
\makeatother
\pagestyle{fancy}
\fancyhf{}
%\rhead{\theauthor}
\lhead{\thetitle}
\cfoot{\thepage}
\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{titlepage}
\centering
\vspace*{0.5 cm}
\includegraphics[scale = 0.3]{resources/logo4.png}\\[1.0 cm]
\textsc{\LARGE \newline\newline UNIX 101}\\[2.0 cm]
\textsc{\Large or "How to feel like a true hack3r"}\\[0.5 cm]
\rule{\linewidth}{0.2 mm} \\[0.4 cm]
{ \huge \bfseries \thetitle}\\
\rule{\linewidth}{0.2 mm} \\[1.5 cm]
% \begin{minipage}{0.5\textwidth}
% \begin{flushleft} \large
% \emph{Professor:}\\
% Renan E P Lima\\
% Departamento de Matemática\\
% \end{flushleft}
% \end{minipage}~
% \begin{minipage}{0.4\textwidth}
%
% \begin{flushright} \large
% \emph{Grupo:} \\
% Gabriel P Crestani\\
% Victor R Sales\\
% \end{flushright}
%
% \end{minipage}\\[2 cm]
\thedate
\end{titlepage}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tableofcontents
\pagebreak
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Foreword}
\subsection{Objective}
This tutorial should teach you the basics of working with a terminal. You are not expected to fully assimilate everything that this document is about in details, but you should at least understand the basics of every notion. You can come back to this tutorial whenever you want to refresh your mind.
If you work thoroughfully, at the end of this tutorial, you should know:
\begin{itemize}
\item What the syntax of a command is
\item A few useful commands
\item How to navigate in a filesystem
\item How to create, edit and remove files
\item What is a packet manager and how to use one
\item How to create your own executable scripts
\end{itemize}
Even thought you may already have a bit of knowledge on the topics we will study, we will start again from the beginning. It will help you assimilate completely the basics and provide you a stronger basis to learn new things.
\subsection{Preliminary setup}
You are going to need a UNIX-like operating system for this tutorial.
A Linux distribution is preferred but a Mac can also do the job (OS X is a variant of FreeBSD).
If your operating system is a Windows, the safest way is for you to start a virtual machine running a Linux distribution although you could also run the Windows Subsystem for Linux\footnote{\url{https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux}}. It allows one to run the latest versions of Ubuntu on a Windows 10 machine, but it is still new, so at your own risk!
\section{Terminal and shell}
\subsection{A terminal?}
To be precise, a \textit{terminal emulator} is a program reading the user's keyboard input.
Inside a terminal runs a \textit{shell}. This is a program that works in pair with a terminal. The shell's job is basically to read the text it is given as input and interpret it into actual actions.
Of course, the shell does not understand random text input; it tries to interpret what the user inputs into commands.
We will detail the syntax of a command later on.
\begin{figure}[!h]\centering\captionsetup{}
\includegraphics[scale = 0.20]{resources/terminal.png}
\caption{This is what a terminal looks like}
\end{figure}
\subsection{Opening a terminal}
Let us try it now! Open a new terminal. On a fresh Ubuntu install, the shortcut is \texttt{Ctrl+T}. On a Mac, you should be able to launch one by first pressing \texttt{Cmd+Space} and then typing "Terminal".
You should be prompted with a window like the following:
\begin{lstlisting}[language=bash]
nico@nico-VirtualBox:~$
\end{lstlisting}
This is called the prompt. Typically, the \texttt{\$} at the end of the line represents the position where you start typing text.
From now on, the examples on this tutorial will all start with that \texttt{\$}.
\subsection{Anatomy of a command and manual}
First, we will call the command \texttt{ls} (list). This program, susprinsigly, allows one to get the \textit{list} of files in the current directory.
\begin{lstlisting}[language=bash]
$ls
Desktop Documents Downloads Music Pictures Public Templates Videos
\end{lstlisting}
That is great! But wait, do not leave yet, there is more. One can alter a command's behavior by adding arguments. See after:
\begin{lstlisting}[language=bash,breaklines=true]
$ls /
bin/ home/ lost+found/ root/ sys/ vmlinuz.old@
boot/ initrd.img@ media/ run/ tmp/
cdrom/ initrd.img.old@ mnt/ sbin/ usr/
dev/ lib/ opt/ snap/ var/
etc/ lib64/ proc/ srv/ vmlinuz@
\end{lstlisting}
Here, the first argument of the command was \texttt{/}. Thus, the command \texttt{ls} changed its behavior to list the root directory (\texttt{/}) instead of the current directory.
Last but not least, arguments can take the form of flags. One can recognize a flag because it begins by a dash (\texttt{-}). In the following example, we use the flag \texttt{-l}:
\begin{lstlisting}[language=bash]
$ls -l /
total 119
drwxr-xr-x 2 root root 4096 déc. 23 19:02 bin/
drwxr-xr-x 4 root root 3072 déc. 23 19:07 boot/
drwxrwxr-x 2 root root 4096 févr. 26 2018 cdrom/
drwxr-xr-x 22 root root 4400 janv. 4 22:38 dev/
drwxr-xr-x 153 root root 12288 déc. 23 22:52 etc/
drwxr-xr-x 4 root root 4096 févr. 26 2018 home/
lrwxrwxrwx 1 root root 33 déc. 23 19:05 initrd.img -> boot/initrd.img-4.15.0-43-generic
lrwxrwxrwx 1 root root 33 déc. 23 19:05 initrd.img.old -> boot/initrd.img-4.15.0-33-generic
drwxr-xr-x 25 root root 4096 sept. 5 09:17 lib/
drwxr-xr-x 2 root root 4096 févr. 26 2018 lib64/
drwx------ 2 root root 16384 févr. 26 2018 lost+found/
drwxr-xr-x 5 root root 4096 mai 15 2018 media/
drwxr-xr-x 7 root root 4096 juin 20 2018 mnt/
drwxr-xr-x 6 root root 4096 juin 4 2018 opt/
dr-xr-xr-x 290 root root 0 janv. 4 19:41 proc/
drwx------ 11 root root 4096 janv. 4 21:49 root/
drwxr-xr-x 34 root root 1100 janv. 4 19:42 run/
drwxr-xr-x 2 root root 12288 déc. 23 19:02 sbin/
drwxr-xr-x 5 root root 4096 sept. 1 19:16 snap/
drwxr-xr-x 2 root root 4096 févr. 15 2017 srv/
dr-xr-xr-x 13 root root 0 janv. 4 19:42 sys/
drwxrwxrwt 15 root root 20480 janv. 5 02:28 tmp/
drwxr-xr-x 12 root root 4096 mars 29 2018 usr/
drwxr-xr-x 14 root root 4096 févr. 15 2017 var/
lrwxrwxrwx 1 root root 30 déc. 23 19:05 vmlinuz -> boot/vmlinuz-4.15.0-43-generic
lrwxrwxrwx 1 root root 30 déc. 23 19:05 vmlinuz.old -> boot/vmlinuz-4.15.0-33-generic
\end{lstlisting}
That is quite a lot of information! The option \texttt{-l} allows one to get much more information than with a simple \texttt{ls}.
To check out the full list of possible arguments you can use with ls, use the command \texttt{man ls}.
The \texttt{man} command gives information about the command given as argument. From now on, this will be your best friend. You can quit the man by pressing \texttt{q}. \textbf{Before asking for help, always check out the manual}. The answer to your question will, in 95\% of the cases, be findable inside.
Also, at the top of every man page is the prototype (\textit{"synopsys"}) of the command. It will help you figure out how you should call it, in which order the arguments can be put and which arguments are mandatory for the command to run.
\subsection{Demystifying "commands"} \label{demystifying_commands}
Actually, the term \textit{command} is not accurate.
When one launches the command \texttt{ls}, the program at location \texttt{/bin/ls} is executed by the shell. Then, in this case, entering in the shell \texttt{ls} is the same as entering \texttt{/bin/ls}, but faster.
Using \texttt{which ls} tells you where the program \texttt{ls} is located.
\begin{lstlisting}[language=bash]
$which ls
/bin/ls
\end{lstlisting}
One simply has to list the content of the directory \texttt{/bin} to verify that \texttt{ls} is a program that lies there:
\begin{lstlisting}[language=bash]
$ls -l /bin
total 13044
(...)
-rwxr-xr-x 1 root root 56152 mars 2 2017 ln
-rwxr-xr-x 1 root root 111496 sept. 22 2016 loadkeys
-rwxr-xr-x 1 root root 48128 mars 26 2019 login
-rwxr-xr-x 1 root root 453856 juin 27 17:49 loginctl
-rwxr-xr-x 1 root root 105136 mars 21 2019 lowntfs-3g
-rwxr-xr-x 1 root root 126584 mars 2 2017 ls
-rwxr-xr-x 1 root root 77280 oct. 10 11:34 lsblk
(...)
\end{lstlisting}
As you can see, the directory \texttt{/bin} contains the program \texttt{ls}!
By the way, \texttt{which} is also a program, so entering \texttt{which which} in the shell works! Feel free to try.
However, some commands do not depend on the programs on your filesystem. They are contained within the shell tool set, literally "built in" the shell. Thus, we call them... built-in commands\footnote{\href{https://unix.stackexchange.com/questions/11454/what-is-the-difference-between-a-builtin-command-and-one-that-is-not}{This question}'s responses might give you a deeper understanding of the difference between these two types of commands}.
Now, how does \texttt{which}, or your shell, knows where to find the program your commands refer to? Well, there is no black magic in UNIX system; the shell does not magically know that the program \texttt{ls} lives in \texttt{/bin}, for example.
There is a special variable that the shell keeps track of: the \texttt{PATH}.
\begin{lstlisting}[language=bash]
$echo $PATH # Show the content of PATH variable
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
\end{lstlisting}
It references all of the location where binaries are supposed to sit, separated by a colon (\texttt{:}).
When the shell encounters a non-builtin command, like \texttt{ls}, it will simply check in all of the locations referenced in the path, one by one, if there is a program named as the command. If there is one, it will start it; if not, it will raise an error.
\subsection{Why the command line?}
Now you may be wondering why bother using fastidious commands to simply show a list of files. It would be way simpler to use a graphical tool like Mac's Finder or Windows's file explorer!
Well, even though it is more complicated to do basic things, the diversity of options shipped with every command allows one to do much more than simply with a graphical user interface (GUI).
It is also possible to combine options, widening the range of possibilites.
The philosophy of UNIX is for each command to be able to do a limited set of things, but to do it perfectly, with performance in mind.
A few other reasons as to why knowing how to work on a command line is important:
\begin{itemize}
\item Many technical actions cannot be done graphically, as a lot of software engineering/sysadmin programs only have a command line interface (CLI)
\item Scripts are essential to computer engineering and are nothing but a list of sequential commands to execute
\item Thanks to their variety of options, command line programs allow one to run complex tasks in a simple line. Imagine how tiresome it would be to copy only .jpeg files of size \textless 100Kb from one huge directory to another using Window's file manager? With the CLI, it is doable with a simple command or a minimal script
\end{itemize}
The bottom line is: in computer science, everybody uses the command line. Just like knowing how to code, knowing how to use the command line is essential in the daily job of anyone working in that field.
\section{Core filesystem utilities}
Now that you have an idea on how to use commands and most importantly on where to find documentation, let us dig into the basics.
In this section, you will learn how to navigate in your filesystem and how to play with it.
Do not forget to take a look at the manual in case of doubt (type \texttt{man} followed by the name of the command you need documentation for).
Before we start using commands, please read thoroughfully the next section.
\subsection{Absolute and relative paths}
The most common use case for shells -and the one we are going to use the most during this tutorial- are interactive-mode shells. When opening a terminal, you are dropped in an interactive shell. When launched in interactive mode, the shell accepts commands, executes them and gives the user control back to run more commands. Additionally, in that mode, the shell maintains a state regarding the filesystem.
The current working directory is hence something that can change depending on commands input by the user. One can "move" from one directory to an other and the shell will keep track of that.
Now, directories and files can be referenced \textbf{in regards to the current directory} or \textbf{in regards to the root of the filesystem}. The former kind of reference is called \textbf{relative} and the latter \textbf{absolute}. An absolute path to a file or directory will stay the same, no matter what is the current directory of the shell; a relative one will depend on what is the current directory of the shell. Using absolute paths is often safer to use because you cannot get them wrong; however, they can get long, which makes them tiring to write down. Relative paths, on the other hand, are easier to write because they are shorter but are more error prone. \newline
\usetikzlibrary{trees,calc}
\tikzset{
every node/.style={
draw=black,
thick,
anchor=west,
inner sep=2pt,
minimum size=1pt,
}
}
\begin{tikzpicture}[
grow via three points={
one child at (0.8,-0.7) and two children at (0.8,-0.7) and (0.8,-1.4)
},
edge from parent path={
($(\tikzparentnode\tikzparentanchor)+(.4cm,0pt)$) |- (\tikzchildnode\tikzchildanchor)
},
growth parent anchor=west,
parent anchor=south west,% = \tikzparentanchor
% child anchor=west,% = \tikzchildanchor
% every child node/.style={anchor=west}% already in "every node"
]
\node { \textbf{/}}
child { node {home/}
child { node [draw=none] {main.html} }
child { node [label={[xshift=6.0cm, yshift=-0.58cm, color=gray] Let this be the working directory }] {nicolas/ }
child { node {work/}
child { node [draw=none] {qcm.pdf}}
child { node [draw=none] {tutorial.pdf}}
}
child [missing] {}
child [missing] {}
child { node {videos/}}
child { node {photos/}}
child { node [draw=none] {\ldots}}
}
child [missing] {}
}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child { node {boot/} }
child { node {tmp/} }
child { node {root/} }
child { node {bin/} }
child { node {etc/} }
child { node [draw=none] {\ldots}};
%child { node {release/}
% child { node [draw=none] {libAwesome.a} }
% child { node [draw=none] {libAwesome.dylib} }
%};
\end{tikzpicture}
Considering this example of filesystem, for a shell with its working directory being \texttt{/home/nicolas/}, there are two possible ways to reference the tutorial file:
\begin{itemize}
\item Absolute path: \texttt{/home/nicolas/work/tutorial.pdf}
\item Relative path: \texttt{./work/tutorial.pdf}
\end{itemize}
\subsection{Filesystem navigation commands}
Let us review the commands that allow you to move around your filesystem.
\subsubsection{ls ("list")}
This is an easy one, we have just learned about it in the last section.
Try to:
\begin{enumerate}
\item List the content of the current directory, including the hidden files\footnote{In UNIX, hidden files' filenames begin with a "."}. What do you think the \texttt{.} and \texttt{..} directories refer to? Remember to use the manual to learn about the things you do not know
\item List the content of \texttt{/etc}. What do you think is inside?
\item List the content of \texttt{/etc} and all of its subdirectories in one command
\end{enumerate}
\subsubsection{pwd ("print working directory")}
This command is super simple. It simply gives you the full path of your shell's current directory.
Try it! Open a new terminal and type \texttt{pwd}.
\begin{lstlisting}[language=bash]
$pwd
/home/nicolas
\end{lstlisting}
This is what is called your \textit{home}. Every user of the computer has its own home directory, where he can put his personal files.
\subsubsection{cd ("change directory")}
This command allows you to move from one directory to another. It is similar to double-clicking on the icon of a directory.
\begin{enumerate}
\item Try to open the man for this command. What happens?
\texttt{cd} is a builtin command (cf. \ref{demystifying_commands}). \texttt{man} works only with actual programs installed on your system. To get help for this kind of commands,
you can use \texttt{help my\_command}.
\item What is the difference between writing \texttt{cd /bin} and \texttt{cd bin}?
\item Move anywhere in your filesystem. Then, type \texttt{cd} without any argument. Where are you now?
\item Move anywhere in your filesystem. Then, type \texttt{cd \~}. Where are you now?
\item Move to \texttt{/etc}, then move to \texttt{/usr}. Finally, type \texttt{cd -}. Where are you now?
\end{enumerate}
\subsection{File manipulation}
Great, we know how to move in our filesystem. Let us start manipulating files and directories!
\subsubsection{mkdir ("make directory")}
As its name indicates it, this command allows one to create a new directory.
\begin{enumerate}
\item Move to your home directory and create a directory named \texttt{code}
\item Move to your home directory and, with a single \texttt{mkdir} command, create the two directories \texttt{code/python} and \texttt{code/python/exo1}
\end{enumerate}
\subsubsection{rmdir ("remove directory")}
As we just saw how to \textit{make} a directory, this allows one to \textit{remove} one.
Note that this command only works on empty directories.
\subsubsection{cp ("copy")}
This one allows one to copy files and directories from a directory to another.
\begin{enumerate}
\item Create a new directory and copy the file \texttt{/etc/hosts} inside
\item Create a new directory and recursively copy all of the files and directories from \texttt{/etc} inside. Can you guess why warnings are printed to the screen?
\end{enumerate}
Also, remember this in the previous section?
\begin{quote}
\textit{Imagine how tiresome it would be to copy only .jpeg files of size \textless 100Kb from one huge directory to another using Window's file manager?}
\end{quote}
With \texttt{cp}, combined with a wildcard\footnote{\url{https://www.shell-tips.com/2006/11/04/using-bash-wildcards/}}, we can super easily copy all files which end with \texttt{.conf}. It would not be too complicated to only select files of size \textless 100Kb, but let's keep this for another time.
This example demonstrates how to copy all files which end with \texttt{.conf} from \texttt{/etc/} to \texttt{/tmp/mdr}.
\begin{lstlisting}[language=bash]
$mkdir /tmp/mdr # Create a new directory called mdr, in /tmp/
$cp /etc/*.conf /tmp/mdr/ # Copy all files that end with.conf from /etc/ to /tmp/mdr/
$ls --format=single-column /tmp/mdr/ # Verify that the files have been correctly copied
adduser.conf
apg.conf
appstream.conf
brltty.conf
ca-certificates.conf
debconf.conf
deluser.conf
fuse.conf
fwupd.conf
gai.conf
hdparm.conf
host.conf
idmapd.conf
insserv.conf
kernel-img.conf
kerneloops.conf
ld.so.conf
lftp.conf
libao.conf
libaudit.conf
logrotate.conf
ltrace.conf
mke2fs.conf
mtools.conf
nsswitch.conf
pam.conf
pnm2ppa.conf
popularity-contest.conf
request-key.conf
resolv.conf
rsyslog.conf
sensors3.conf
signond.conf
smi.conf
sysctl.conf
ucf.conf
updatedb.conf
usb_modeswitch.conf
\end{lstlisting}
\subsubsection{mv ("move")}
The \texttt{mv} command allows one to move a file or directory somewhere else. It is similar to a "Cut\&Paste".
It can also be used to rename a file.
\begin{enumerate}
\item Create a new directory, copy the file \texttt{/etc/hosts} inside and rename it \texttt{file1}.
\item Duplicate \texttt{file1} and create another directory. With one command, move both files to that new directory
\end{enumerate}
\subsubsection{rm ("remove")}
This command allows one to remove a file from the filesystem.
Be careful when using it as you will not be prompted a warning when you are attempting to delete a file. What is more, there is no "Trash bin" in the command line world. Once a file is deleted, it is gone for good.
\begin{enumerate}
\item Remove every file and directory you put in your home directory in the previous exercises
\end{enumerate}
\subsubsection{touch}
Last but not least, the command \texttt{touch} allows one to change the time of last modification of a file. Honestly, it is not very useful, but it is possible to use it to create empty files:
\begin{lstlisting}[language=bash]
$mkdir test
$cd test
$touch hello
$ls
hello
$
\end{lstlisting}
\subsection{Peek inside files}
We have manipulated directories and files but we still do not know how to show their content. Let us dig into this now.
\subsubsection{cat ("catenate", it seems)}
This command simply displays the content of the files given as argument.
\begin{enumerate}
\item If you run a Linux distribution, read the content of \texttt{/etc/os-release}
\item If you run another system, read the content of \texttt{/etc/shells} instead
\item What do you think the file \texttt{/etc/os-release} refers to?
\item Read the content of \texttt{/etc/hosts} and \texttt{/etc/services} in just one command
\item Using an option of cat, find out how many lines are inside the file \texttt{/etc/services}\footnote{There is a command called \texttt{wc} which is specialized in counting the number of lines, but let us not use this one for now :)}
\end{enumerate}
\subsubsection{head \& tail}
These two commands are similar to \texttt{cat} but only display the beginning (head) or the end (tail) of a file. It can be useful to read the beginning or the end huge files.
The number of lines displayed default to 10, but it can be changed with an option.
\begin{enumerate}
\item Display the first 20 lines of \texttt{/etc/protocols}
\item Display the last two bytes of \texttt{/etc/hosts}. Display the last byte of \texttt{/etc/hosts}. Why do you think you get this result? Using the \texttt{-E} option of cat, identify what the last byte of this file is
\end{enumerate}
\subsubsection{less}
This program is a pager. It allows one to look into a file without having to load all of its content into memory (hence the name, it \textit{paginates}). It is extremely useful when dealing with huge files, like servers logs.
This pager is invoked using \texttt{less path\_to\_file} and provides the user a way to:
\begin{enumerate}
\item Navigate in between the lines: press \textit{up} and \textit{down} arrow keys or \textit{j} and \textit{k})
\item Move to top or bottom: press \textit{g} or \textit{G}
\item Search for the occurrences of a work: press \textit{/}, write your word, press \textit{Enter} and navigate through the occurrences using \textit{n} and \textit{N}
\item And many more...
\end{enumerate}
Use \textit{h} to get some help inside the pager and press {\textit{q}} to leave.
The design of \texttt{less} might make you think of \texttt{man}. That is because \texttt{man} is also a pager. The shortcuts we just went through can also be used when reading a man page! Useful when trying to look for specific information :)
\section{File editor, package manager and permissions}
Great, we have seen many things. But we are still not able to edit files. Let us remediate to this
\subsection{File editor}
There are many file editors\footnote{We will not discuss IDEs in this tutorial} available in the terminal world. Pick one in the following list.
\begin{description}
\item[vim:] This is a highly configurable text editor. It is lightweight and designed to optimize writing code. There is an incredible set of shortcut and commands to your disposal, which allow you to do tons of advanced things.
Also, it is an in-terminal software, meaning that you will stay in the same terminal window as the one you currently are in when you invoke it.
Still, beware, because it is not an easy task to get started with using \textbf{vim}. The controls are not-intuitive\footnote{Many are similar to the pager's}, so it is a pain to get started with it.
\item[nano:] Just like \textbf{vim}, \textbf{nano} is an in-terminal software. It is simpler to use but provides less features.
\item[gedit:] It is a primitive GUI editor bundled with GNOME\footnote{\url{https://en.wikipedia.org/wiki/GNOME_Shell}}. It aims at simplicity and is perfect for performing simple editing tasks.
\item[Atom:] A GUI editor. It provides a beautiful and clean interface. One can also install plugins and themes to customize it. It is described as a \textit{hackable text editor}: combine plugins and your configuration to make it your own.
Only downside: it is a bit slow at times.
\item[sublimeText:] Very similar to Atom, but in general faster.
\end{description}
\subsection{Choose your fighter!}
If you do not feel at ease and want to go for the easiest thing, go for \textbf{gedit}.
If you feel adventurous and wish to take the difficult path, go for \textbf{vim}. Knowing how to do basic stuff with this tool is always useful as pretty much every UNIX machine in the world has at least \textbf{vim} or \textbf{vi} (simpler vim)\footnote{Useful when you have are controling a server remotely and only have access to a terminal!}. You can get away with using vim thanks to the following tips:
\begin{itemize}
\item Do not use the mouse, it will not work well
\item Upon opening a file, hit \texttt{i} to begin writing text: you will enter insert mode
\item When you are done and want to quit, hit \texttt{ESC}, then write \texttt{:wq} to save\&quit or \texttt{:q!} to quit without saving
\item Pay attention to the mode you are currently in: if it is written \texttt{INSERT} at the bottom left of the screen, that means that you are in insert mode and you can type text. If it is written something else, hit \texttt{ESC} to go back the default mode
\end{itemize}
If you do not feel comfortable learning how to use an in-terminal text editor like vim, but still want to use something sophisticated, my advice for you is to pick either \textbf{Atom} or \textbf{sublimeText}.
\subsection{You chose gedit or nano!}
Chances are that \textbf{nano} and \textbf{gedit} are already installed in your system. To check, simply use the command \texttt{which}. This command allows one to get the location of the program.
\begin{lstlisting}[language=bash]
$which nano
/bin/nano
$which gedit
/usr/bin/gedit
\end{lstlisting}
You are ready to edit files! You can skip the next sections dealing with text editors. Still, read the content of those as they contain information that you need to know.
\subsection{You chose vim!}
Chances are that \textbf{vim} is not installed in your system. To check, simply use the command \texttt{which}. This command allows one to get the location of the program.
\begin{lstlisting}[language=bash]
$which vim
$
\end{lstlisting}
As you can see, \texttt{which} prints nothing, so that means that the command \texttt{vim} is not found by your shell. It most likely means that the program is not installed.
This is the perfect opportunity to learn how to install programs in UNIX-like systems!
\subsubsection{Package manager}
A package manager is a tool allowing one to install, uninstall and update \textit{packages}.
A package is simply an archive containing source code and/or applications.
Ubuntu's default packet manager is \texttt{apt}. Mac OS does not have one, but you can install \texttt{brew}\footnote{\url{https://brew.sh/}}.
A look at the man indicates us that we can install a package using \texttt{apt install package\_name} (\texttt{brew install package\_name} for Mac users).
\begin{lstlisting}[language=bash]
$apt install vim
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
$
\end{lstlisting}
Oops, that did not work. It seems that we do not have sufficient permissions! We can bypass this using the \texttt{sudo} command. It allows one to launch commands as administrator (\textit{root}). Keep this in mind, we will talk about permissions in the next section.
\begin{lstlisting}[language=bash]
# Note: while typing your password, nothing gets printed to the screen. Don't panic, that's normal, simply type your password and hit enter :)
$sudo apt install vim
[sudo] password for nico: Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
vim-runtime
Suggested packages:
ctags vim-doc vim-scripts
The following NEW packages will be installed:
vim vim-runtime
0 upgraded, 2 newly installed, 0 to remove and 297 not upgraded.
Need to get 6 589 kB of archives.
After this operation, 32,0 MB of additional disk space will be used.
Do you want to continue? [Y/n]
\end{lstlisting}
Here, we enter \texttt{Y} and press enter to validate. Informational text is displayed and we get control back. Let us check that we installed \texttt{vim} correctly:
\begin{lstlisting}[language=bash]
$which vim
/usr/bin/vim
$
\end{lstlisting}
Great, it worked!
Refer to the manual for more information on \texttt{apt} (how to remove packages, how to upgrade software and how to update the list of available packages).
\subsubsection{Installing packages manually}
In the previous section, we studied how to install programs with \texttt{apt} or \texttt{brew}.
Keep in mind that not every program is available in the official package repositories. This is the case for \textbf{Atom} and \textbf{sublimeText}. We will detail in this section how to manually install a software.
So, let us say we want to install \textbf{Atom} on a fresh Ubuntu system.
\begin{lstlisting}[language=bash]
$sudo apt install atom
[sudo] password for nicolas:
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package atom
$
\end{lstlisting}
Here, the error message is pretty explicit: \texttt{apt} could not find a package containing the program \texttt{atom}. We will have to install it ourselves.
Going to their official site, we can download a \texttt{.deb} file: \url{https://atom.io/download/deb}.
Once saved to our system, we will simply call the following \texttt{dpkg}\footnote{Actually, \texttt{apt} uses \texttt{dpkg} underneath the calls to its high-level API} command to install it.
\begin{lstlisting}[language=bash]
$ls Downloads
atom-amd64.deb
$sudo dpkg -i Downloads/atom-amd64.deb
[sudo] password for nicolas:
Selecting previously unselected package atom.
(Reading database ... 364547 files and directories currently installed.)
Preparing to unpack Downloads/atom-amd64.deb ...
Unpacking atom (1.33.1) ...
Setting up atom (1.33.1) ...
Processing triggers for desktop-file-utils (0.22-1ubuntu5.2) ...
Processing triggers for bamfdaemon (0.5.3~bzr0+16.04.20180209-0ubuntu1) ...
Rebuilding /usr/share/applications/bamf-2.index...
Processing triggers for gnome-menus (3.13.3-6ubuntu3.1) ...
Processing triggers for mime-support (3.59ubuntu1) ...
$which atom
/usr/bin/atom
\end{lstlisting}
There you have it!
\subsubsection{Finally, editing a file!}
Now that your favorite editor is installed, simply invoke it with the name of the file you want to create:
\begin{lstlisting}[language=bash]
$cd Documents
# This works with gedit and all the other tools. Simply replace "vim" by the name of your text editor
$vim my_document # or gedit my_document or nano my_document or atom my_document...
# Now, either a pop-up appears or your terminal is replaced by the text editor. In most cases you CANNOT use your terminal until the text editor is closed
(...editing...)
# Once you save your modifications and close the text editor, you can re-use your terminal
$cat my_document
Hello!
$
\end{lstlisting}
\subsection{Permissions and root user}
Remember in last section when we encountered a \textit{Permission denied} error? Let us explain what happened here.
\subsubsection{File permissions}
\begin{lstlisting}[language=bash]
$apt install vim
apt install vim
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
$
\end{lstlisting}
It seems that, for some reason, \texttt{apt} needed to open the file \texttt{/var/lib/dpkg/lock-frontend}.
In UNIX-like systems, each file is attributed a set of permissions:
\begin{itemize}
\item read (\textbf{r}, value \textbf{4}): this permission allows one to get the content of a file or to list the content of a directory
\item write (\textbf{w}, value \textbf{2}): this allows one to edit the content of a file\footnote{Not renaming or destruction of a file. Permissions for this kind of operation are a bit more complex: \url{https://unix.stackexchange.com/a/230508}}
\item execute (\textbf{x}, value \textbf{1}): this last permission allows one to execute a file if it is a program or a script. If it is a directory, this means that the user can move to it
\end{itemize}
There is thus a total of 8 different possible combinations:
\begin{table}[ht]
\centering
\begin{tabular}[t]{lcc}
\toprule
&Textual representation &Numerical representation\\
\midrule\
No permission&\textbf{---}&\textbf{0}\\
Execute-only&\textbf{--x}&\textbf{1}\\
Write-only&\textbf{-w-}&\textbf{2}\\
Write \& execute&\textbf{-wx}&\textbf{3} (2 + 1)\\
Read-only&\textbf{r--}&\textbf{4}\\
Read \& execute&\textbf{r-x}&\textbf{5} (4 + 1)\\
Read \& write&\textbf{rw-}&\textbf{6} (4 + 2)\\
Read \& write \& execute&\textbf{rwx}&\textbf{7} (4 + 2 + 1)\\
\bottomrule
\end{tabular}
\caption{The 8 file permissions combinations}
\end{table}%
\subsubsection{File ownership}
In UNIX-like systems, we say that a file is owned by a user. If the user \texttt{nicolas} creates a file, he will be the owner.
Linking that distinction to the mechanism of file permissions, a file in your filesystem is supposed to have three triplets of permissions: one for the user which owns it, one for the group of the user which owns it and lastly one for every other user of the system.
This "triple triplet" is in the following order: \textit{user, group, others}.
\begin{figure}[!h]\centering\captionsetup{}
\includegraphics[scale = 0.65]{resources/permissions.png}
\caption{Permissions of a file}
\end{figure}
\subsubsection{Showing a file's permissions}
The \texttt{-l} option of \texttt{ls} allows one to show files in the \textit{long-listing format}, including the owner of the file and the file permissions.
\begin{figure}[!h]\centering\captionsetup{}
\includegraphics[scale = 0.65]
{resources/llformat.png}
\caption{Long listing format}
\end{figure}
Let us try:
\begin{lstlisting}[language=bash]
$touch my_file
$ls -l my_file
-rw-rw-r-- 1 nicolas nicolas 0 janv. 7 01:48 my_file
\end{lstlisting}
Here, the owner is \texttt{nicolas} and so is the group of the owner. The access rights say that I can read or modify the file and so can the members of the group \texttt{nicolas}. However, users not in the group \texttt{nicolas} only have read access.
Let us see another example:
\begin{lstlisting}[language=bash]
$which mkdir
/bin/mkdir
$ls -l /bin/mkdir
-rwxr-xr-x 1 root root 76848 mars 2 2017 /bin/mkdir*
\end{lstlisting}
The file \texttt{/bin/mkdir}, which I invoke using the command \texttt{mkdir}, is owned by the \texttt{root} user (i.e the administrator). The \texttt{root} user can read it, modify it and execute it. The members of its group can only read it and execute it. I can also read it and execute it. Let us verify:
\begin{lstlisting}[language=bash]
# Read permission
$head -c 4 /bin/mkdir
ELF$
# Write permission
$ rm /bin/mkdir
rm: remove write-protected regular file '/bin/mkdir'? y
rm: cannot remove '/bin/mkdir': Permission denied
# Execute permission
$/bin/mkdir /tmp/my_new_directory
$ls -d /tmp/my_new_directory
/tmp/mydir/
$
\end{lstlisting}
Knowing this and the fact that \texttt{sudo my\_command} launches \texttt{my\_command} as the \texttt{root} user, can you troubleshoot why we could not open the file \texttt{/var/lib/dpkg/lock} as a simple user?
\begin{lstlisting}[language=bash]
ls -lh /var/lib/dpkg/lock
-rw-r----- 1 root root 0 janv. 6 22:32 /var/lib/dpkg/lock
\end{lstlisting}
\subsubsection{Modifying permissions}
The file owner and the root user can both modify the permissions of a file. One calls the \texttt{chmod} command for that.
There are different ways to invoke \texttt{chmod}. The following lines are examples that will help you understand how one changes the three triplets of permissions for a file.
\begin{description}
\item[Octal representation:] The first digit represents the right of the owner, the second digit the rights of its group and the last one the rights associated to all the other users
\begin{lstlisting}[language=bash]
# Set read-only rights for everybody
$chmod 444 my\_file
# Set read-write-execute rights for the user, read-write for the users of its group and read-only for other users
$chmod 764 my\_file
\end{lstlisting}
\item[Symbolic representation:] With symbolic representation, you do not set permissions, you add (\textbf{+}) or remove (\textbf{-}) them to the \textbf{u}ser, \textbf{g}roup and/or \textbf{o}thers.
\begin{lstlisting}[language=bash]
# Add write permission for the other users
$chmod o+w my_file
# Remove execute permission for owning user and its group
$chmod ug-x my_file
# Add read-write permissions to user and its group and read for others
$chmod ug+rw o+r my_file
# If invoked without u, g or o, it defaults to ugo: this adds the execute permission on the file for all users
$chmod +x my_file
# This is similar to the following (a stands for all)
$chmod a+x my_file
\end{lstlisting}
\end{description}
It is also possible to modify the file owner using the command \texttt{chown}. We will not go throught this one though.
\subsection{Creating your own programs}
Did you think creating your own scripts was a difficult task? Actually, you have pretty much all the cards in your hands right now to create your very own programs. You know how to create a file, edit it and set it executable.
\subsubsection{A shell script}
Let us create our very own shell script now! Using your favorite text editor, create a file called \texttt{my\_ls.sh}.
Although this is not absolutely needed, it is a good practice to start a script with a \textit{shebang}. A \textit{shebang} is a line indicating which program is supposed to run the script. It is made of a sharp (\texttt{\#}), a bang (\texttt{!}) and the full path of the program which will run the script.
A shell script can be run using \texttt{bash}, the shell that we have been using since the beginning of this tutorial, or any other shell (\texttt{sh}, \texttt{zsh}, etc).
First of all, locate bash's full path. Open a terminal and type the following:
\begin{lstlisting}[language=bash]
$which bash
/bin/bash
\end{lstlisting}
Then, write the shebang at the beginning of your script:
\begin{lstlisting}[language=bash]
#! /bin/bash
\end{lstlisting}
Then, you can start building your script. A shell script is simply a list of commands. Shell being a script language, there exists conditional statement, loops and many much more. For now, we have not studied the subject enough, so let us simply call a simple command with fancy options: a recursive \texttt{ls} with long-listing format, also displaying hidden files.
\begin{lstlisting}[language=bash]
#! /bin/bash
ls -Rahl
\end{lstlisting}
That's it. We have our first program, a \texttt{ls} on steroids! Now, the syntax to launch a program is as follows\footnote{It also is possible to directly call the executable: \texttt{/bin/bash my\_ls.sh} or \texttt{/bin/python3 my\_python\_program.py}}:
\begin{lstlisting}[language=bash]
$./my_ls.sh
bash: ./my_ls.sh: Permission denied
\end{lstlisting}
Oops, something is wrong. We forgot to make the file executable. Easy, let us use \texttt{chmod}.
\begin{lstlisting}[language=bash]
$chmod +x my_ls.sh
$./my_ls.sh
(huge output)
\end{lstlisting}
It works! :)
Now, this is a very simple example, but remember that Shell is a full-fledged language: there are conditions, loops, arrays and all. You can build real applications with it!
\subsubsection{A python script}
You have seen how to write a shell script, but it was not that useful nor impressive, since you may not have sufficient knowledge in this scripting language.
Python being an interpreted language, one can write Python scripts just as Shell scripts. There is below the code for a number guessing game. With basic notions of Python, you should be able to get what it is doing easily. We will make a script out of this snippet, and run it inside the terminal.
First, install Python3:
\begin{lstlisting}[language=bash]
# For Ubuntu users
$sudo apt install python3-pip
\end{lstlisting}
\begin{lstlisting}[language=bash]
# For Mac OS users
$brew install python3
\end{lstlisting}
Now, find the absolute path to Python3's binary:
\begin{lstlisting}[language=bash]
$which python3
/usr/bin/python3
\end{lstlisting}
Finally, create a file named \texttt{guessing\_game.py} and paste the following code snippet inside (\href{https://pastebin.com/U6XG2NF5}{click here}). Do not forget to change the shebang if it does not fit the location of your python3 binary.
\begin{lstlisting}[language=python]
#! /usr/bin/python3
# The random package is needed to choose a random number
import random
# Define the game in a function
def guess_loop():
# This is the number the user will have to guess, chosen randomly in between 1 and 100
number_to_guess = random.randint(1, 100)
print("I have in mind a number in between 1 and 100, can you find it?")
# Replay the question until the user finds the correct number
while True:
try:
# Read the number the user inputs
guess = int(input())
# Compare it to the number to guess
if guess > number_to_guess:
print("The number to guess is lower")
elif guess < number_to_guess:
print("The number to guess is higher")
else:
# The user found the number to guess, let's exit
print("You just found the number, it was indeed", guess)
return
# A ValueError is raised by the int() function if the user inputs something else than a number
except ValueError as err:
print("Invalid input, please enter an integer")
# Launch the game
guess_loop()
\end{lstlisting}