Extra

Creare de noi directoare într-o ierarhie

Pentru a crea un nou director în directorul curent folosim comanda mkdir.

student@uso:~/.../basics/toddler-s bottle/passcode$ cd ~/uso.git/labs/01-fs/support/basics
student@uso:~/.../01-fs/support/basics$ ls
grotesque  'hacker-s secret'   rookiss  'toddler-s bottle'
student@uso:~/.../01-fs/support/basics$ mkdir my-new-folder
student@uso:~/.../01-fs/support/basics$ ls
grotesque  'hacker-s secret'   my-new-folder   rookiss  'toddler-s bottle'

În cazul în care vrem să creăm un director al cărui nume conține spații, avem 2 posibilități.

Varianta 1:

student@uso:~/.../01-fs/support/basics$ mkdir "weird directory"
student@uso:~/.../01-fs/support/basics$ ls
grotesque          my-new-folder  'toddler-s bottle'
'hacker-s secret'   rookiss        'weird directory'

Varianta 2:

student@uso:~/.../01-fs/support/basics$ mkdir weird\ directory\ 2
student@uso:~/.../01-fs/support/basics$ ls
 grotesque          my-new-folder  'toddler-s bottle'  'weird directory 2'
'hacker-s secret'   rookiss        'weird directory'

Intrați în primul director creat. Vrem să creăm un fișier cu conținutul “Hello, world”.

student@uso:~/.../01-fs/support/basics$ cd w<TAB>
student@uso:~/.../support/basics/weird directory$ echo "Hello, world" > my_file.txt
student@uso:~/.../support/basics/weird directory$ ls -l
total 4
-rw-r--r-- 1 student student 13 aug 21 22:59 my_file.txt

Până a trece mai departe, trebuie să vă asigurați că ați înțeles cum puteți crea noi fișiere și directoare. Pentru asta, parcurgeți următoarele exerciții după care verificați cu asistentul că totul este în regulă. Recomandăm folosirea paginii de manual pentru utilitarul ls (man ls). Vă va da informații despre toate argumentele pe care le puteți da comenzii ls.

  1. Vă aflați în weird directory. Creați directorul cu numel third weird directory la calea basics/toddler-s\ bottle. Mutați-vă la acea cale.
  2. Creați un fișier gol cu numele my_second_file.txt.
  3. Modificați conținutul fișierului și afișați conținutul acestuia folosind comanda cat. Puteți folosi orice editor de text doriți pentru face modificări asupra fișierului.

Mutarea fișierelor și directoarelor

Pentru a redenumi un fișier folosim comanda mv. Comanda mv are formatul mv sursă destinație. În cazul în care uitați, folosiți pagina de manual a acesteia.

student@uso:~/.../basics/toddler-s bottle/third weird directory$ cd ~/uso.git/labs/01-fs/support/basics/toddler-s\ bottle
student@uso:~/.../support/basics/toddler-s bottle$ ls
bof         fd     input      random
collision   flag   passcode  'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ mv collision my-new-collision
student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   flag    my-new-collision   random
 fd    input   passcode          'third weird directory'

Bineînțeles, putem redenumi un fișier aflat într-un alt director.

student@uso:~/.../support/basics/toddler-s bottle$ cd ~/uso.git/labs/01-fs/support/basics/toddler-s\ bottle
student@uso:~/.../support/basics/toddler-s bottle$ ls ../grotesque/do\ you\ dare/
ascii  dos4fun  elf  hunter  hunting  mipstake  rootkit
student@uso:~/.../support/basics/toddler-s bottle$ mv ../grotesque/do\ you\ dare/mipstake ../grotesque/do\ you\ dare/mistake
student@uso:~/.../support/basics/toddler-s bottle$ ls ../grotesque/do\ you\ dare?/
ascii  dos4fun  elf  hunter  hunting  mistake  rootkit

Folosim tot comanda mv pentru a muta un fișier într-un alt director.

student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   flag    my-new-collision   random
 fd    input   passcode          'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ ls ../hacker-s\ secret/
 hard   medium  'really hard'
student@uso:~/.../support/basics/toddler-s bottle$ mv my-new-collision ../hacker-s\ secret/ # păstrand numele
student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   fd   flag   input   passcode   random  'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ ls ../hacker-s\ secret/
 hard   medium   my-new-collision  'really hard'

Există posibilitatea să mutăm un fișier într-un alt director și să-i schimbăm numele în același timp.

student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   fd   flag   input   passcode   random  'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ ls ../hacker-s\ secret/
 hard   medium   my-new-collision  'really hard'
student@uso:~/.../support/basics/toddler-s bottle$ mv flag ../hacker-s\ secret/my-new-flag # schimbând numele
student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   fd   input   passcode   random  'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ ls ../hacker-s\ secret/
 hard   medium   my-new-collision   my-new-flag  'really hard'

În cazul în care avem mai multe fișiere de mutat într-un alt (același) director, folosim tot comanda mv.

student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   fd   input   passcode   random  'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ ls ../rookiss/
'ascii easy.pdf'   echo2     loveletter   syscall
'brain fuck'       fix.pdf   otp.pdf
student@uso:~/.../support/basics/toddler-s bottle$ mv fd input ../rookiss
student@uso:~/.../support/basics/toddler-s bottle$ ls
 bof   passcode   random  'third weird directory'
student@uso:~/.../support/basics/toddler-s bottle$ ls ../rookiss
'ascii easy.pdf'   echo2   fix.pdf   loveletter   syscall
'brain fuck'       fd      input     otp.pdf

Până a trece mai departe în cadrul acestei secțiuni, trebuie să ne asigurăm că ați înțeles cum funcționează comanda mv. Rezolvați exercițiile următoare până să treceți mai departe. Consultați-vă cu asistentul pentru orice nelămurire.

  1. Mutați fișierul grotesque/asg în directorul grotesque/do\ you\ dare/ din locul în care vă aflați.
  2. Mutați fisierele elf hunter mistake din directorul grotesque/do\ you\ dare/ în directorul părinte al acestora.
  3. Navigați către directorul hacker-s\ secret și mutați directorul hard în directorul home al utilizatorului curent.
  4. Plasați-vă în directorul toddler-s\ bottle/bof/easy. Mutați în directorul basics toate fișierele ale căror nume încep cu bof și se termină cu .txt. (Hint: wildcards)

Pentru a redenumi un fișier am văzut că folosim comanda mv. În cazul în care vrem ca noul nume să conțină spații, procedăm ca mai devreme (vezi crearea directoarelor).

student@uso:~/.../toddler-s bottle/bof/easy$ cd ~/uso.git/labs/01-fs/support/basics
student@uso:~/.../01-fs/support/basics$ ls
 bof1.txt   bof4.txt   'hacker-s secret'  'toddler-s bottle'
 bof2.txt   bof5.txt    my-new-folder     'weird directory'
 bof3.txt   grotesque   rookiss           'weird directory 2'
student@uso:~/.../01-fs/support/basics$ mv rookiss/ "my new rookiss"
student@uso:~/.../01-fs/support/basics$ ls
 bof1.txt   bof4.txt   'hacker-s secret'  'toddler-s bottle'
 bof2.txt   bof5.txt    my-new-folder     'weird directory'
 bof3.txt   grotesque   'my new rookiss'    'weird directory 2'

Putem întâlni sitația în care vrem să redenumim un fișier al cărui nume conține deja spații, acestea trebuie escapate ca mai devreme. Putem scrie numele între ghilimele, însă există riscul să greșim în cazul numelor complicate și lungi. Cel mai sigur și ușor este să abuzăm de tasta <TAB> pentru a fi siguri că nu greșim. Vrem să modificăm numele directorului weird directory în weird directory again.

student@uso:~/.../01-fs/support/basics$ mv w<TAB> "weird directory again"
student@uso:~/.../01-fs/support/basics$ ls
 bof1.txt   bof4.txt   'hacker-s secret'  'toddler-s bottle'
 bof2.txt   bof5.txt    my-new-folder     'weird directory 2'
 bof3.txt   grotesque   'my new rookiss'    'weird directory again'

Până a trece mai departe, trebuie să ne asigurăm că ați reținut cum trebuie lucrat în cazul în care avem de-a face cu nume de fișiere/directoare care conțin spații. Până să treceți la următoarea secțiune, parcurgeți următoarele exerciții și consultați-vă cu asistentul.

  1. Mutați fișierul toddler-s\ bottle/passcode/random-org în directorul curent fără a naviga către acel fișier. (Hint: directorul curent este .)
  2. Copiați toate fișierele ale căror nume conțin spații din directorul toddler-s\ bottle/bof/hard în directorul home al utilizatorului curent fără a schimba directorul curent. (Hint: man cp)

Ștergerea fișierelor și directoarelor

Ne-a rămas o singură comandă de bază despre care nu am vorbit, ștergerea. Pentru a șterge un fișier, folosim comanda rm. Înainte să

student@uso:~/.../01-fs/support/basics$ cd ~/uso.git/labs/01-fs/support/basics/grotesque
 coin2  'do you dare'   elf   hunter   mistake
student@uso:~/.../support/basics/grotesque$ rm coin2
student@uso:~/.../support/basics/grotesque$ ls
'do you dare'   elf   hunter   mistake

Avem posibilitatea de a șterge fișiere multiple folosind o singură comandă. Pentru asta, va trebui să pasăm ca argument comenzii toate fișierele pe care dorim să le ștergem.

student@uso:~/.../support/basics/grotesque$ cd ~/uso.git/labs/01-fs/support/basic/toddler-s\ bottle/bof/easy
student@uso:~/.../toddler-s bottle/bof/easy$ ls
bof-bof-bof  can-you-bof  random-bof.txt
student@uso:~/.../toddler-s bottle/bof/easy$ rm bof-bof-bof can-you-bof
student@uso:~/.../toddler-s bottle/bof/easy$ ls
random-bof.txt

Ne aflăm în directorul ~/uso.git/labs/01-fs/support/basics/grotesque și vrem să ștergem un fișier dintr-un alt director fără a schimba directorul în care ne aflăm. Putem face acest lucru ușor dându-i comenzii rm calea către acel fișier (fie absolută, fie relativă).

student@uso:~/.../support/basics/grotesque$ ls
'do you dare'   elf   hunter   mistake
student@uso:~/.../support/basics/grotesque$ rm ../toddler-s\ bottle/bof/medium/getting-serious-here  
student@uso:~/.../support/basics/grotesque$ ls ../toddler-s\ bottle/bof/medium
student@uso:~/.../support/basics/grotesque$

În cazul în care vrem să ștergem un întreg director, comanda rm <nume_director> nu va funcționa. Trebuie să îi precizăm că vrem să ștergem recursiv toate fișierele și subdirectoarele din aceasta ierarhie. Pentru acest lucru, folosim argumentul -r al comenzii rm. Dacă directorul pe care vrem să-l ștergem este gol, putem folosi și comanda rmdir.

student@uso:~/.../support/basics/grotesque$ cd ~/uso.git/labs/01-fs/support/basics
student@uso:~/.../01-fs/support/basics$ ls
 bof1.txt   bof5.txt           'my new rookiss'      'weird directory again'
 bof2.txt   grotesque          random-org
 bof3.txt  'hacker-s secret'  'toddler-s bottle'
 bof4.txt   my-new-folder     'weird directory 2'
student@uso:~/.../01-fs/support/basic$ rm -r "weird directory again"
student@uso:~/.../01-fs/support/basic$ ls
 bof1.txt   bof4.txt   'hacker-s secret'   random-org
 bof2.txt   bof5.txt    my-new-folder     'toddler-s bottle'
 bof3.txt   grotesque   'my new rookiss'    'weird directory 2'
student@uso:~/.../01-fs/support/basic$ rmdir weird\ directory\ 2/
student@uso:~/.../01-fs/support/basic$ ls
 bof1.txt   bof4.txt   'hacker-s secret'   random-org
 bof2.txt   bof5.txt    my-new-folder     'toddler-s bottle'
 bof3.txt   grotesque   'my new rookiss'

Pentru a vă asigura că ați înțeles cum se șterg fișierele și directoarele dintr-o ierarhie, parcurgeți următoarele exerciții și consultați-vă cu asistentul în cazul oricărei nelămuriri.

  1. Mergeți în directorul my new rookiss și ștergeți fișierul syscall.
  2. În cadrul aceluiaș director, ștergeți fișierele loveletter și input folosind o singură comandă.
  3. Rămâneți în acest director. Ștergeți fișierul random-org din directorul părinte.
  4. Ștergeți directorul really hard din hacker-s secret.
  5. Ștergeți toate fișierele ale căror nume conțin spații din directorul toddler-s\ bottle/bof/hard.
  6. Ștergeți toate fișierele cu extensia .txt din directorul toddler-s\ bottle/bof/easy.
  7. Folosind o singură comandă, ștergeți tot conținutul directorului basics.

Căutare în interiorul fișierelor

Mai departe vom căuta în interiorul fișierelor dintr-o ierarhie. Vom folosi utilitarul grep. Acesta se folosește astfel:

student@uso:~/uso.git$ grep --help
Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE.
Example: grep -i 'hello world' menu.h main.c

Cuvântul cheie grep urmat de opțiuni și de cuvântul cheie pe care îl căutam. Putem afla aceste opțiuni prin folosirea comenzii man grep sau grep –help la fel ca la utilitarul locate. Astfel, putem observa că există opțiunea -r cu care putem căuta recursiv intr-o ierarhie de fișiere.

Vrem să căutam apariția int main() in ierarhia de fișiere ~/uso.git. Mergem în această ierarhie folosind cd ~/uso.git.

student@uso:~/uso.git$ grep -r "int main()"
tema1/year/year.c:int main(){
lab03/ugly/ugly.c:}int main()
tema4/headers/hello_5.c:int main()
tema4/headers/hello_3.c:int main()
tema4/headers/hello_7.c:int main()
tema4/headers/hello_2.c:int main()
tema4/headers/hello_1.c:int main()
tema4/headers/hello_6.c:int main()
tema4/headers/hello_4.c:int main()
tema4/headers/hello_0.c:int main()
lab02/anul_1/programare/simple_math.c:int main()
lab02/anul_1/programare/hello.c:int main()
lab02/anul_1/programare/teme/tema3/main.c:int main()
lab02/anul_1/programare/teme/tema3/src/floats.c:int main()
lab02/anul_1/programare/teme/tema3/src/constants.c:int main()
lab02/anul_1/programare/teme/tema2/floats.c:int main()
lab02/anul_1/programare/teme/tema2/constants.c:int main()
lab02/anul_1/programare/teme/tema1/simple_math.c:int main()
lab02/anul_1/programare/teme/tema1/hello.c:int main()
lab02/anul_1/programare/teme/tema4/main.c:int main()
lab02/anul_1/programare/teme/tema4/src/floats.c:int main()
lab02/anul_1/programare/teme/tema4/src/constants.c:int main()

[1c] Căutați în interiorul fișierelor în ierarhia de fișiere ~/uso.git patternul “include <stdio.h>“. Folosiți grep recursiv.

3. Compilare automata - Makefile

În directorul ~/uso.git/labs/01-fs/support/need-to-know/3-compile avem 2 fișiere: Makefile si hello_world.c. Rolul fișierului Makefile este de a compila sursa hello_word.c. Putem compila și executa fișierul obținut astfel:

student@uso:~/uso.git$ make
gcc -o hello_world hello_world.c
student@uso:~/uso.git$ ./hello_world 
Hello, World!

[3a] Intrați în directorul uso/labs/01-fs/support/need-to-know/. Rulați executabilul din calea 3-compile obtinut anterior din directorul curent. Hint: puteti vedea opțiunile utilitarului make folosint man make sau make –help la fel ca utilitarele folosite precedent.

[3b] Rămâneți în directorul uso/labs/01-fs/support/need-to-know/. Copiați 3-compile/Makefile in directorul curent, rulați Makefile și executați binarul obținut.

[3c] Creați un nou director numit nu_intrati și în cadrul acestuia un fișier sursă manele_2018.c în care să afișați un text la alegere. Copiați Makefile-ul folosit anterior și adaptați-l pentru cazul vostru. Compilați executabilul folosind Makefile și rulați executabilul.

Redirectare

Utilitarul df afișează informații despre sistemul de fișiere precum ocuparea acestuia. Folosirea acestuia:

student@uso:~/uso.git$ df --help
Usage: df [OPTION]... [FILE]...
Show information about the file system on which each FILE resides,
or all file systems by default.

Cuvântul cheie df urmat de opțiuni și de numele fișierului. Fără numele fișierului, afișează informații despre întreg sistemul. Putem afla aceste opțiuni prin folosirea comenzii man df sau df –help la fel ca la utilitarele locate, mkdir și grep.

Redirectarea rezultatului se face prin operatorul >. Astfel:

student@uso:~/uso.git$ df -h > informatii_sistem
student@uso:~/uso.git$ cat informatii_sistem
Filesystem      Size  Used Avail Use% Mounted on
udev            968M     0  968M   0% /dev
tmpfs           200M  1,3M  199M   1% /run
/dev/sda1        16G  6,1G  8,9G  41% /
tmpfs           997M     0  997M   0% /dev/shm
tmpfs           5,0M  4,0K  5,0M   1% /run/lock
tmpfs           997M     0  997M   0% /sys/fs/cgroup
/dev/loop0       87M   87M     0 100% /snap/core/5145
/dev/loop1       87M   87M     0 100% /snap/core/4917
/dev/loop2       13M   13M     0 100% /snap/gnome-characters/103
/dev/loop3       35M   35M     0 100% /snap/gtk-common-themes/319
/dev/loop7       15M   15M     0 100% /snap/gnome-logs/37
/dev/loop4      3,8M  3,8M     0 100% /snap/gnome-system-monitor/51
/dev/loop6      2,4M  2,4M     0 100% /snap/gnome-calculator/180
/dev/loop5      141M  141M     0 100% /snap/gnome-3-26-1604/70
tmpfs           200M   28K  200M   1% /run/user/1000

Bineînteles, am verificat că redirectarea a avut succes prin afișarea conținutului fișierului în care am redirectat.

[2d] Redirectați în fișierul ierarhiei.txt rezultatul comenzii tree. Comanda trebuie executată din vârful ierarhiei.

[2e] Repetați redirectarea de mai sus în fișierul ierarhie_ascii, dar de data aceasta în format ASCII.

Corectare lucru cu fișier header și Makefile

În directorul ~/uso.git/labs/01-fs/support/04-compile/ găsiți un set de fișiere și un fișier Makefile pentru compilarea lor. Există o eroare ce ține de căi în sistemul de fișiere, astfel că nu merge compilarea în momentul rulării comenzii make.

Corectați eroarea și obțineți fișierul executabil write_hello.

Comenzi și executabile

Comenzile pe care le rulăm au la bază fișiere executabile în sistemul de fișiere. În momentul în care dăm o comandă, shell-ul caută într-o listă predefinită de directoare existența unui executabil cu ajutorul căruia să ruleze comanda respectivă. De exemplu, comanda ls folosește executabilul /bin/ls, astfel că rularea celor două comenzi de mai jos este echivalentă:

ls
/bin/ls

Similar, comanda find foloseșt executabilul /usr/bin/find, comanda zip folosește executabilul /usr/bin/zip și așa mai departe.

Directoarele în care caută shell-ull executabilele aferente unei comenzi se găsesc într-o construcție de tip variabilă de mediu numită PATH. Vom vorbi mai multe despre variabile și variabile de mediu la un laborator viitor. Pe moment, este suficient să știm că pentru a afișa valoarea variabilei PATH folosim comanda

student@uso:~/uso.git/labs/01-fs$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Directoarele afișate, conținute de variabila PATH sunt afișate în rezultatul comenzii, separate prin caracterul : (două puncte, colon). Asta înseamnă ca dacă un utilizator tastează comanda ls, shell-ul va căuta, în ordine, existența executabilului /usr/local/sbin/ls, apoi /usr/local/bin/ls, apoi /usr/sbin/ls și așa mai departe. Când găsește un executabil îl va rula, ducând la afișarea rezultatului comenzii la terminal.

Calea către executabilul aferent unei comenzi poate fi afișată folosind comanda which urmată de numele comnezii, ca mai jos:

student@uso:~/uso.git/labs/01-fs$ which ls
/bin/ls
student@uso:~/uso.git/labs/01-fs$ which find
/usr/bin/find
student@uso:~/uso.git/labs/01-fs$ which zip
/usr/bin/zip

În rulările celor trei comenzi which de mai sus am obținut calea către fișierele executabilele aferente respectiv comenzilor ls, find și zip.

Putem verifica faptul că acele fișiere sunt executabile prin folosirea comenzii file urmată de calea către fișierul executabil, cal mai jos:

student@uso:~/uso.git/labs/01-fs$ file /bin/ls
/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped
student@uso:~/uso.git/labs/01-fs$ file /usr/bin/find
/usr/bin/find: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=b920f53e0c67a31d8ef07b84b1344f87a0e82d71, stripped
student@uso:~/uso.git/labs/01-fs$ file /usr/bin/zip
/usr/bin/zip: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=c828586e6e7cf929500a5b9c04faece9eceed5cc, stripped

În rezultatul rulării celor trei comenzi file de mai sus vedem că apare informația ELF, dynamically linked. Fără a intra în detalii, acest lucru este indiciul că aceste fișiere sunt, într-adevăr fișiere executabile.

[6a] Găsiți fișierele executabilele aferente comenzilor useradd, iotop, tar, gzip. Verificați că cele patru fișiere indicate sunt fișiere executabile.

Bonus: De ce fișierele executabile pentru useradd și iotop se găsesc într-un director care conține sbin/ pe când tar și gzip se găsesc într-un director care conține bin/ (fără s)? Folosiți Internetul și Google pentru aflarea răspunsului.

Parcurgere fișiere folosind ''find''

O situație frecventă în lucrul cu fișiere este să parcurgem toate fișierele dintr-o ierarhie. Eventual să facem apoi operații pe toate aceste fișiere: să schimbăm permisiuni, să afișăm informații, să ștergem unele fișiere. Pentru aceasta folosim utilitarul find.

În mod implicit find afișează recursiv toate intrările din directorul curent, așa cum se vede când rulăm comanda

student@uso:~/uso.git/labs/01-fs$ find
.
./wiki
./wiki/basics.wiki
./wiki/concepts.wiki
./wiki/demo.wiki
./wiki/get-a-life.wiki
./wiki/nice-to-know.wiki
./wiki/recap.wiki
./wiki/need-to-know.wiki
./01-fs-g.zip
./support
./support/.gitignore
./support/get-a-life
[...]

Dacă-i dăm un argument un director, va afișa recursiv toate intrările din acel director. De exemplu, comanda de mai jos afișează toate intrările din ierarhia /var/lib/apt/:

student@uso:~/uso.git/labs/01-fs$ find /var/lib/apt
/var/lib/apt
/var/lib/apt/mirrors
/var/lib/apt/mirrors/partial
/var/lib/apt/daily_lock
/var/lib/apt/lists
[...]

[3a] Putem afișa folosind find doar anumite tipuri de intrări, de exemplu doar fișiere. Pentru a afișa doar fișierele din directorul curent folosim opțiunea -type f, la fel ca în comanda de mai jos:

student@uso:~/uso.git/labs/01-fs$ find -type f
./wiki/basics.wiki
./wiki/concepts.wiki
./wiki/demo.wiki
./wiki/get-a-life.wiki
./wiki/nice-to-know.wiki
./wiki/recap.wiki
[...]

Observăm în output că sunt afișate numai fișiere, folosind opțiunea -type f.

[3b] Putem afișa fișierele care corespund unui anumit pattern. De exemplu pentru a afișa toate fișierele cu extensia .tex vom folosi opțiunea -name, la fel în comanda de mai jos:

student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.tex'
./support/nice-to-know/fruits/pear.tex
./support/get-a-life/4-rename/5.tex
./support/get-a-life/4-rename/3.tex
[...]

Observăm că sunt afișate numai fișierele cu extensia .tex.

[3c] Putem folosi comanda find pentru a aplica o altă comandă pe intrările găsite. De exemplu dacă dorim să ștergem toate fișierele cu extensia .c vom folosi opțoiunea -exec, la fel ca în comanda de mai jos:

student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.c'
./support/nice-to-know/fruits/apple.c
./support/get-a-life/2-passwd/reader.c
student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.c' -exec rm {} \;
student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.c'
student@uso:~/uso.git/labs/01-fs$

Dacă la început aveam două fișiere cu extensia .c (./support/nice-to-know/fruits/apple.c și ./support/get-a-life/2-passwd/reader.c) după rularea comenzii find acele fișiere dispar.

Contrucția -exec rm {} \; este mai complicată și nu o vom explica în detaliu aici. Pe scurt:

  • -exec este opțiunea care dictează comenzii find să execute comanda primită ca argument
  • rm este comanda rulată pentru fiecare fișier găsit, adică acea comandă care șterge fișierul
  • {} este o construcție specifică opțiunii -exec care înlocuiește numele fișierului; practic înseamnă că rulăm rm <nume-fisier> pentru fiecare fișier descoperit
  • \; este un terminator de comandă, spunând că aici se încheie comanda transmisă argument opțiunii -exec

[3d] Pe baza celor de mai sus, ștergeți toate fișierele temporare din ierarhia curentă.

Fișierele temporare sunt fișiere care se încheie cu caracterul ~ (tildă).

1. Redirectări

Pentru acest set de exerciții trebuie să vă aflați în directorul ~/uso.git/labs/. Folosiți comanda:

cd ~/uso.git/labs

De multe ori dorim să salvăm rezultatul afișat de o comandă (output) într-un fișier pentru a-l consulta ulterior. Acest lucru este util pentru comenzile care afișează multe informații pe care nu le putem vizualiza ușor sau pentru a reține snapshot-uri ale rulării unei comenzi pe care să le comparăm între ele. De exemplu, dacă rulăm comanda

ls > out.txt

Vom obține în fișierul out.txt rezultatul rulării comenzii ls. Putem verifica acest lucru cu ajutorul comenzii

cat out.txt

Operatorul > din shell este numit operator de redirectare, cu ajutorul căruia redirectăm rezutatul comenzii (adică ieșirea standard, standard output) în fișierul trimis ca argument.

Un caz de utilizare este atunci când dorim să rulăm o comandă fără a ne preocupa rezultatul rulării acesteia. În acest caz redirectăm ieșirea standard a comenzii la fișierul special /dev/null. Fișierul special /dev/null este un fișier de tipul “gaură neagră”: orice informație redirectată acolo se pierde.

Pentru a exemplifica redirectarea în fișierul special /dev/null vom folosi utilitarul/comanda strace. Comanda strace monitorizează apelurile pe care le face o altă comandă către sistemul de operare (stracesystem call tracing). Pentru început rulăm comanda de mai jos și obținem rezultatul indicat:

student@uso:~/uso.git/labs$ strace ls
execve("/bin/ls", ["ls"], 0x7ffdde615410 /* 35 vars */) = 0
brk(NULL)                               = 0x5651b5da3000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[...]
write(1, "00-intro  01-fs  02-process  03-"..., 10900-intro  01-fs  02-process  03-user  04-appdev  05-cli  06-hw-boot  07-storage  08-net  09-vm	10-sec	11-ctf
[...]

Comanda strace primește ca argument o altă comandă și argumentele aceleia. În cazul de mai sus, a primit ca argument comanda ls. Apoi comanda strace afișează la ieșirea standard (standard output) rezultatul comenzii primite ca argument (la noi ls) iar la ieșirea de eroare standard (standard error) rezultatul propriu (adică sumarul apelurilor pe care îl face comanda primită ca argument la sistemul de operare).

Pe moment nu este nevoie să știți bine cum folosim comanda strace. O folosim ca să demonstrăm aspecte ale redirectării și pentru că scenariile pe care le prezentăm sunt practice și utile.

O comandă poate afișa informații la ieșirea standard (standard output) și la ieșirea de eroare standard (standard error). Ambele informații sunt afișate pe ecranul terminalului. La ieșirea standard sunt mesajele generate util de comandă, în vreme ce la ieșirea de eroare standard sunt mesajele de eroare și avertisment (warning) afișate în condiții deosebite.

[1a] Ne dorim să afișăm la terminal doar rezultatul comenzii strace, adică apelurile realizate de comanda primită ca argument, fără să ne preocupe rezultatul comenzii. Pentru aceasta redirectăm ieșirea standard la /dev/null, adică în acel fișier special gaură neagră. Rulăm acum fără redirectare și cu redirectare comenzile de mai jos pentru a investiga fișierele deschise de comanda ls:

student@uso:~/uso.git/labs$ strace -e openat ls
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
00-intro  01-fs  02-process  03-user  04-appdev  05-cli  06-hw-boot  07-storage  08-net  09-vm	10-sec	11-ctf	strace.out
+++ exited with 0 +++
student@uso:~/uso.git/labs$ strace -e openat ls > /dev/null
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
+++ exited with 0 +++

În cazul redirectării ieșirii standard la fișierul special /dev/null folosind operatorul >, observăm că nu mai apare listarea de fișiere 00-intro … reprezentând rezultatul comenzii ls.

Argumentul -e openat al comenzii strace ne permite să selectăm doar apelurile de deschidere de fișier pe care comanda primită ca argument (în cazul nostru ls) le face la sistemul de operare.

[1b] Într-o situație ne interesează să redirectăm rezultatul comenzii strace într-un fișier; adică acea înlănțuire de apeluri efectuate de comanda primită ca argument către sistemul de operare. Pentru aceasta, folosim operatorul 2> de redirectare a ieșirii de eroare standard (standard error) ca mai jos:

student@uso:~/uso.git/labs$ strace -e openat ls 2> strace.out
00-intro  01-fs  02-process  03-user  04-appdev  05-cli  06-hw-boot  07-storage  08-net  09-vm	10-sec	11-ctf

În comanda de mai sus ieșirea de eroare standard (standard error) a fost redirectată în fișierul strace.out; adică rezultatul comenzii strace, adică șirul de apeluri ale comenzii ls la sistemul de operare. La terminal a fost afișată ieșirea standard a comenzii, adică rezultatul comenzii ls.

Verificăm faptul că redirectarea a avut loc cu succes afișând conținutul fișierului strace.out cu ajutorul comenzii

student@uso:~/uso.git/labs$ cat strace.out
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
+++ exited with 0 +++

Observăm că, așa cum ne așteptam, rezultatul comenzii strace (lista de apeluri) a fost redirectată cu succes în fișier prin redirectarea ieșirii de eroare standard (standard error).

[1c] Ne poate interesa să redirectăm și rezultatul comenzii strace într-un fișier și rezultatul comenzii primite ca argument. În acest caz folosim atât operatorul > de redirectare a ieșirii standard (standard output) cât și operatorul 2> de redirectare a ieșirii de eroare standard (standard error). Pentru aceasta folosim comanda:

student@uso:~/uso.git/labs$ strace -e openat ls 2> strace.out > ls.out

În comanda de mai sus am redirectat ieșirea standard (standard output), adică rezultatul comenzii ls, în fișierul ls.out și ieșirea de eroare standard (standard error), adică rezultatul comenzii strace, în fișierul strace.out. Putem verifica acest lucru prin afișarea conținutului celor două fișiere:

student@uso:~/uso.git/labs$ cat strace.out
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
+++ exited with 0 +++
student@uso:~/uso.git/labs$ cat ls.out
00-intro
01-fs
02-process
03-user
04-appdev
05-cli
06-hw-boot
07-storage
08-net
09-vm
10-sec
11-ctf
ls.out
strace.out

Observăm că cele două fișiere obținute în urma redirectării (strace.out și ls.out) conțin rezultatele rulării comenzilor.

[1d] Construiți o comandă strace care să nu afișeze nimic la terminal și să aibă în fișierul strace.out apelurile de deschidere de fișiere realizate de comanda ps.

A nu afișa nimic la terminal înseamnă că trebuie să ignorați rezultatul comenzii ps, adică să folosiți redirectarea către fișierul special /dev/null.

[1e] Utilitarul grep este folosit pentru a căuta un șir de caractere într-un fișier. De exemplu comanda de mai jos caută șirul root în fișierul /etc/passwd:

student@uso:~/uso.git/labs$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash

După rularea unei comenzi putem folosi comanda echo $? pentru a vedea dacă s-a rulat cu succes. De exemplu, dacă după rularea comenzii grep de mai sus, rulăm comanda de verificare a unei rulări cu succes, obținem:

student@uso:~/uso.git/labs$ echo $?
0

Rezultatul 0 înseamnă o comandă anterioară s-a rulat cu succes.

Construiți o comanda grep cu redirectare care să nu afișeze nimic la terminal (nici standard output, nici standard error). Iar după rularea acelei comenzi să verificați rularea cu succes. Pentru a verifica faptul că ați construit comanda grep cum trebuie, folosind secvența de comenzi de mai jos:

student@uso:~/uso.git/labs$ grep 'a' /etc/passwd TODO
student@uso:~/uso.git/labs$ echo $?
0
student@uso:~/uso.git/labs$ grep 'aaa' /etc/passwd TODO
student@uso:~/uso.git/labs$ echo $?
1
student@uso:~/uso.git/labs$ grep 'aaa' /etc/pass TODO
student@uso:~/uso.git/labs$ echo $?
2

În loc de TODO trebuie să completați cu acele părți din construcție care folosesc redirectre pentru a nu afișa nimic la terminal.

3. Parcurgere fișiere folosind ''find''

O situație frecventă în lucrul cu fișiere este să parcurgem toate fișierele dintr-o ierarhie. Eventual să facem apoi operații pe toate aceste fișiere: să schimbăm permisiuni, să afișăm informații, să ștergem unele fișiere. Pentru aceasta folosim utilitarul find.

În mod implicit find afișează recursiv toate intrările din directorul curent, așa cum se vede când rulăm comanda

student@uso:~/uso.git/labs/01-fs$ find
.
./wiki
./wiki/basics.wiki
./wiki/concepts.wiki
./wiki/demo.wiki
./wiki/get-a-life.wiki
./wiki/nice-to-know.wiki
./wiki/recap.wiki
./wiki/need-to-know.wiki
./01-fs-g.zip
./support
./support/.gitignore
./support/get-a-life
[...]

Dacă-i dăm un argument un director, va afișa recursiv toate intrările din acel director. De exemplu, comanda de mai jos afișează toate intrările din ierarhia /var/lib/apt/:

student@uso:~/uso.git/labs/01-fs$ find /var/lib/apt
/var/lib/apt
/var/lib/apt/mirrors
/var/lib/apt/mirrors/partial
/var/lib/apt/daily_lock
/var/lib/apt/lists
[...]

[3a] Putem afișa folosind find doar anumite tipuri de intrări, de exemplu doar fișiere. Pentru a afișa doar fișierele din directorul curent folosim opțiunea -type f, la fel ca în comanda de mai jos:

student@uso:~/uso.git/labs/01-fs$ find -type f
./wiki/basics.wiki
./wiki/concepts.wiki
./wiki/demo.wiki
./wiki/get-a-life.wiki
./wiki/nice-to-know.wiki
./wiki/recap.wiki
[...]

Observăm în output că sunt afișate numai fișiere, folosind opțiunea -type f.

[3b] Putem afișa fișierele care corespund unui anumit pattern. De exemplu pentru a afișa toate fișierele cu extensia .tex vom folosi opțiunea -name, la fel în comanda de mai jos:

student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.tex'
./support/nice-to-know/fruits/pear.tex
./support/get-a-life/4-rename/5.tex
./support/get-a-life/4-rename/3.tex
[...]

Observăm că sunt afișate numai fișierele cu extensia .tex.

[3c] Putem folosi comanda find pentru a aplica o altă comandă pe intrările găsite. De exemplu dacă dorim să ștergem toate fișierele cu extensia .c vom folosi opțiunea -exec, la fel ca în comanda de mai jos:

student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.c'
./support/nice-to-know/fruits/apple.c
./support/get-a-life/2-passwd/reader.c
student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.c' -exec rm {} \;
student@uso:~/uso.git/labs/01-fs$ find -type f -name '*.c'
student@uso:~/uso.git/labs/01-fs$

Dacă la început aveam două fișiere cu extensia .c (./support/nice-to-know/fruits/apple.c și ./support/get-a-life/2-passwd/reader.c) după rularea comenzii find acele fișiere dispar.

Contrucția -exec rm {} \; este mai complicată și nu o vom explica în detaliu aici. Pe scurt:

  • -exec este opțiunea care dictează comenzii find să execute comanda primită ca argument
  • rm este comanda rulată pentru fiecare fișier găsit, adică acea comandă care șterge fișierul
  • {} este o construcție specifică opțiunii -exec care înlocuiește numele fișierului; practic înseamnă că rulăm rm <nume-fisier> pentru fiecare fișier descoperit
  • \; este un terminator de comandă, spunând că aici se încheie comanda transmisă ca argument opțiunii -exec

[3d] Pe baza celor de mai sus, ștergeți toate fișierele temporare din ierarhia curentă.

Fișierele temporare sunt fișiere care se încheie cu caracterul ~ (tildă).

4. Corectare lucru cu fișier header și Makefile

În directorul ~/uso.git/labs/01-fs/support/04-compile/ găsiți un set de fișiere și un fișier Makefile pentru compilarea lor. Există o eroare ce ține de căi în sistemul de fișiere, astfel că nu merge compilarea în momentul rulării comenzii make.

Corectați eroarea și obțineți fișierul executabil write_hello.

uso/laboratoare/new/01-fs-extra.txt · Last modified: 2018/10/03 22:08 by razvan.deaconescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0