User Tools

Site Tools


medium-unix:capitole:capitol-05

5. Funcționarea shell-ului

Ne interesează internele shell-ului și modul în care acesta execută comenzi. Urmărim să știm ce facilități ne oferă shell-ului pentru a ne face mai rapid și mai productiv activitățile cu sistemul de operare.

Subiecte abordate

  • Pornirea unui shell: shell-uri și terminale, /etc/passwd
  • Scripturi de startup ale shell-ului
  • Rularea unei comenzi de către shell
  • Subshell-uri
  • Variabile shell, variabile de mediu
  • Operatori shell
  • Caractere speciale shell
  • Globbing

Bune practici

  • Comenzi care primesc informații la intrarea standard și comenzi care primesc informații ca parametru: operatorul | vs. expandarea comenzilor $(...)
  • Folosire variabile de mediu doar la nevoie; de prefixat comenzi cu inițializare de variabile
  • Comenzi folosite pentru afișare și comenzi folosite pentru prelucrare
  • Măsoară de două ori și taie o dată :-)
  • Activare reverse search tcsh: http://stackoverflow.com/a/7771746

Utilitare folosite

  • bash, lsof
  • echo
  • type, which
  • env, set
  • find, stat, pgrep

Resurse utile

Slide-uri

Exerciții

Demo-uri

Pornirea unui shell folosind programul login și apoi /etc/passwd. Variabila SHELL

Terminalul unui shell și descriptorii standard de fișier pentru un shell

Ce acțiuni realizează shell-ul la rularea unei comenzi, rularea unei comenzi în background

Determinarea comenzilor builtin și a comenzilor externe (type și which).

Diferența între:

ps ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; ps

și

ps ; /bin/echo ; /bin/echo ; /bin/echo ; /bin/echo ; /bin/echo ; /bin/echo ; /bin/echo ; /bin/echo ; ps

Crearea de subshell-uri, problema cu

echo | read v

Actualizarea variabilei de mediu PATH. Definirea de noi variabile de mediu. Prefixarea unei comenzi cu inițializarea unei variabile de mediu

Expandarea comenzilor:

stat -c "%s" $(find /etc/ -type f -name '*.conf' -size +5k)
lsof -p $(pgrep bash | tr '\n' ',')

Operații pe șiruri în shell

Globbing

Dorim să afișăm toate fișierele cu extensia .conf din /etc, care încep cu a, b, c, d sau e:

ls -l /etc/[a-e]*.conf

Dorim să afișăm fișierele (sau directoarele) cu extensiile .conf sau .d din /etc:

ls -ld /etc/*{.conf,.d}

De ce am folosit parametrul -d la ls?

Dorim să afișăm fișierele (sau directoarele) cu extensiile .conf sau .d din /etc care nu încep cu a, b, c:

ls -ld /etc/[^abc]*{.conf,.d}

Mesaj de întâmpinare în shell

Dorim să afișăm un mesaj de întâmpinare custom pentru momentul în care un utilizator deschide un shell. Mesajul vrem să fie

Welcome, <nume-utilizator>, to Pearson-Hardman-Specter. <nume-utilizator> just got Litt-up!

unde <nume-utilizator> este username-ul.

Pentru aceasta va trebui să editați, ca root (adică folosind sudo), fișierul /etc/bash.bashrc și să scrieți la sfârșitul fișierului comanda dorită. Comanda va fi rulată la orice deschidere de shell nou. Folosiți comanda sudo vim /etc/bash.bashrc pentru a edita ca root fișierul /etc/bash.bashrc.

Fișierul /etc/bash.bashrc este un fișier global de configurare a shell-ului. Fișierul este parcurs la fiecare deschidere de shell.

Pentru început afișați șirul Welcome la fiecare deschidere de shell. Adică scrieți la sfârșitul fișierului /etc/bash.bashrc comanda pentru afișarea șirului. Apoi deschideți un shell nou (sau un tab nou de shell pentru verificare).

Pentru a afișa un mesaj folosiți comanda echo urmată de șirul de afișat. Este recomandat ca șirul de afișat, transmis ca argument comenzii echo să fie pus între ghilimele (", quotes).

Pentru afișarea șirului dorit, care conține username-ul, folosiți variabila USER, variabilă deja definită în shell. Variabila USER conține username-ul. Pentru a afișa valoarea unei variabile folosim construcția de forma $USER. De exemplu, pentru a afișa numele de utilizator și un mesaj de salut folosim comanda

echo "Salut, $USER"

Ca să testați deschideți un tab nou de terminal; la deschiderea terminalului vi se va crea shell-ul și vi se va afișa mesajul din /etc/bash.bashrc.

Folosire globbing

Descărcați și despachetați arhiva de aici.

Listați, folosind globbing, toate imaginile cu extensiile bmp, jpg, png, gif din directorul rezultat în urma dezarhivării.

Pentru a lista toate fișierele cu extensiile bmp, jpg, png și gif folosiți operatorii de globbing * (star) si {opt1,opt2,opt3} (acolade). Un exemplu simplu de utilizare (porniți de la acesta) este

ls practic/*/*.png

Expandarea comenzii

Creați o arhivă tar.gz cu fișierele din ierarhia /etc/ care au extensia .conf și au dimensiunea mai mare de 5KB.

Folosiți comanda tar și apoi expandare de comandă find. Vedeți și exemplele de comenzi de la demo-ul legat de expandarea comenzilor.

Creați o arhivă zip cu fișierele din ierarhia /usr/include care conțin șirul epoll,

Folosiți opțiunea -r a comenzii grep pentru a căuta recursiv într-o ierarhie. Folosiți opțiunea -l a comenzii grep pentru a afișa doar numele fișirelor găsite.

Afișare caractere speciale

Inițializați variabila text la un șir de caractere.

Adică rulați ceva de genul:

text="mellon"

Afișați la ieșirea standard mesajul "Variabila text are valoarea '"...'". Valorea poate fi actualizata.". În mesaj, toate caracterele ghilimele () și apostrof (') se vor afișa întocmai. Iar în loc de puneți valoarea variabile text.

Pentru a afișa ghilimele atunci când deja vă aflați între ghilimele va trebui să le escapați. Escaparea se face folosind \ (backslash).

Alternativa este să închideți ghilimele inițiale și apoi să afișați ghilimelele pe care vreți să afișați între apostrofuri. Invers pentru escaparea de apostrofuri.

Nu puteți escapa apostrofuri câtă vreme vă aflați între apostrofuri.

De exemplu dacă vrem să afișăm șirul ana'are"mere putem folosi

echo ana"'"are'"'mere

Urmăriți ce face comanda

echo "'"'"'ana-are-mere'"'"'"

Afișare fișiere localizate

Folosiți comanda locate pentru a afișa fișierele din sistem care au extensia .conf.

Pentru fișierele de mai sus afișați directoarele din care fac parte.

Folosiți comanda dirname pentru extragerea directoarelor din lista de fișiere extrasă mai sus. Folosiți expandarea comenzilor, adică construcția $(...), în conjuncție cu comanda locate rulată mai sus.

Eliminați duplicatele.

Folosiți operatorul | pentru a redirecta comanda de mai sus către comanda sort -u.

Pentru directoarele de mai sus afișați numele directorului și inode-ul, separate prin virgulă (,).

Folosiți comanda stat cu opțiunea -c și formatul corespunzător.

Bonus: Sortați directoarele de mai sus în ordinea inode-ului. Afișați numele directorului și inode-ul (separate prin virgulă (,)).

Afișare fișiere executabile pentru procese

Afișați procesele al căror proces părinte este init, procesul cu PID-ul 1.

Pentru procesele de mai sus afișați doar comanda completă.

Filtrați doar acele comenzi care încep cu / (adică este calea completă către executabil).

Selectați doar calea către executabil, fără argumente către acesta.

Pentru executabilele de mai sus afișați numele și timpul ultimei schimbării (change time), separate prin virgulă (,).

Folosiți comanda stat.

Sortați executabilele de mai sus în ordinea timpului ultimei schimbări.

Sortarea poate fi simplă, nu este nevoie de sortare numerică. Formatul datei afișat de stat permite sortare de orice fel.

Creare fișiere

Creați 100 de fișiere cu numele "myfile-XY.txt", unde XY este indexul fișierului între 00 și 99.

Folosiți comenzile seq și touch.

Ca model folosiți-vă de comanda

seq -f "%02g" 1 100

Între ghilimele poate apărea un șir complet. Gândiți-vă că trebuie să generați șiruri de forma myfile-XY.txt.

Expandare aritmetică

Din fișierul de aici dorim să extragem partea care începe de la offset-ul 0x13000 (în hexazecimal) până la sfârșit. Puneți conținutul într-un alt fișier. Afișați conținutul primilor 16 octeți din fișier în format hexazecimal; output-ul trebuie să fie de forma 0080 b67f 6a01 7900 1180 0000 b57f b57f.

Pentru a extrage o parte dintr-un fișier folosiți comanda dd. Folosiți opțiunea skip a dd.

Pentru că operați pe octeți, nu pe blocuri, va trebui să configurați pentru dd dimensiunea blocului la 1 folosind opțiunea bs.

Dacă avem un număr în hexazecimal putem folosi construcția de expandare aritmetică $(...) pentru a-l converti în zecimal. De exemplu:

user@hostname:~$ echo $((0x10)), $((0x20)), $((0x100))
16, 32, 256

medium-unix/capitole/capitol-05.txt · Last modified: 2016/05/19 10:32 by razvan