Stații de lucru online OnWorks Linux și Windows

logo

Găzduire online gratuită pentru stații de lucru

<Înapoi | Cuprins | Următor>

Capcane

În capitolul 10, am văzut cum programele pot răspunde la semnale. Putem adăuga această capacitate și la scripturile noastre. În timp ce scripturile pe care le-am scris până acum nu au nevoie de această capacitate (deoarece au timpi de execuție foarte scurti și nu creează fișiere temporare), scripturile mai mari și mai complicate pot beneficia de o rutină de gestionare a semnalului.

Când proiectăm un script mare și complicat, este important să luăm în considerare ce se întâmplă dacă utilizatorul se deconectează sau oprește computerul în timp ce scriptul rulează. Când are loc un astfel de eveniment, un semnal va fi trimis tuturor proceselor afectate. La rândul lor, programele care reprezintă acele procese pot efectua acțiuni pentru a asigura o terminare corectă și ordonată a programului. Să presupunem, de exemplu, că am scris un script care a creat un fișier temporar în timpul execuției acestuia. În cursul unui design bun, scriptul ar trebui să ștergă fișierul când scriptul își termină activitatea. De asemenea, ar fi inteligent ca scriptul să ștergă fișierul dacă este primit un semnal care indică faptul că programul va fi terminat prematur.

pocni oferă un mecanism în acest scop cunoscut sub numele de a capcană. Capcanele sunt implementate cu comanda încorporată numită corespunzător, capcană. capcană folosește următoarea sintaxă:

capcană semnal argument [semnal...]

Unde argument este un șir care va fi citit și tratat ca o comandă și semnal este specificarea unui semnal care va declansa executarea comenzii interpretate.

Iată un exemplu simplu:



#! / Bin / bash


# trap-demo: demonstrație simplă de gestionare a semnalului

#! / Bin / bash


# trap-demo: demonstrație simplă de gestionare a semnalului


capcană „echo „Te ignor.” SIGINT SIGTERM pentru i în {1..5}; do

echo "Iterația $i de 5" somn 5

făcut

capcană „echo „Te ignor.” SIGINT SIGTERM pentru i în {1..5}; do

echo "Iterația $i de 5" somn 5

făcut


Acest script definește o capcană care va executa un ecou comanda de fiecare dată când semnalul SIG-INT sau SIGTERM este primit în timp ce scriptul rulează. Execuția programului arată astfel când utilizatorul încearcă să oprească scriptul apăsând Ctrl-c:


[eu@linuxbox ~]$ trap-demo

Iterația 1 din 5

Iterația 2 din 5 Vă ignor. Iterația 3 din 5 Vă ignor. Iterația 4 din 5

Iterația 5 din 5

[eu@linuxbox ~]$ trap-demo

Iterația 1 din 5

Iterația 2 din 5 Vă ignor. Iterația 3 din 5 Vă ignor. Iterația 4 din 5

Iterația 5 din 5


După cum putem vedea, de fiecare dată când utilizatorul încearcă să întrerupă programul, mesajul este tipărit.

Construirea unui șir pentru a forma o secvență utilă de comenzi poate fi incomodă, așa că este o practică obișnuită să specificați o funcție shell ca comandă. În acest exemplu, este specificată o funcție shell separată pentru fiecare semnal care trebuie gestionat:



#! / Bin / bash

# trap-demo2: demo simplă de gestionare a semnalului exit_on_signal_SIGINT () {

echo "Scriptul întrerupt." 2>&1 ieșire 0

}


exit_on_signal_SIGTERM () {

echo "Scriptul încheiat." 2>&1 ieșire 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM

#! / Bin / bash

# trap-demo2: demo simplă de gestionare a semnalului exit_on_signal_SIGINT () {

echo "Scriptul întrerupt." 2>&1 ieșire 0

}


exit_on_signal_SIGTERM () {

echo "Scriptul încheiat." 2>&1 ieșire 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM



pentru i în {1..5}; do

echo "Iterația $i de 5" somn 5

făcut


pentru i în {1..5}; do

echo "Iterația $i de 5" somn 5

făcut


Acest script are două capcană comenzi, câte una pentru fiecare semnal. Fiecare capcană, la rândul său, specifică o funcție shell care trebuie executată atunci când este recepționat un anumit semnal. Rețineți că includerea unui ieşire comandă în fiecare dintre funcțiile de manipulare a semnalului. Fără o ieşire, scriptul va continua după finalizarea funcției.

Când utilizatorul apasă Ctrl-c în timpul execuției acestui script, rezultatele arată astfel:



[eu@linuxbox ~]$ capcană-demo2

Iterația 1 din 5

Iterația 2 din 5 Scriptul a fost întrerupt.

[eu@linuxbox ~]$ capcană-demo2

Iterația 1 din 5

Iterația 2 din 5 Scriptul a fost întrerupt.


imagine

Fișiere temporare

Unul dintre motivele pentru care manipulatorii de semnal sunt incluși în scripturi este eliminarea fișierelor temporare pe care scriptul le poate crea pentru a păstra rezultate intermediare în timpul execuției. Numirea fișierelor temporare este o artă. În mod tradițional, programele de pe sisteme asemănătoare Unix își creează fișierele temporare în / tmp director, un director partajat destinat unor astfel de fișiere. Cu toate acestea, deoarece directorul este partajat, acest lucru ridică anumite probleme de securitate, în special pentru programele care rulează cu privilegii de superutilizator. Pe lângă pasul evident de stabilire a permisiunilor adecvate pentru fișierele expuse tuturor utilizatorilor sistemului, este important să se acorde fișierelor temporare nume de fișiere care nu sunt previzibile. Acest lucru evită un exploit cunoscut sub numele de a atac de cursă temporară. O modalitate de a crea un nume neprevizibil (dar totuși descriptiv) este să faci ceva de genul acesta:

tempfile=/tmp/$(nume de bază $0).$$.$RANDOM

Aceasta va crea un nume de fișier constând din numele programului, urmat de ID-ul de proces (PID), urmat de un număr întreg aleatoriu. Rețineți, totuși, că $RAN- DOM Variabila shell returnează doar o valoare în intervalul 1-32767, care nu este un interval foarte mare în termeni informatici, deci o singură instanță a variabilei nu este suficientă pentru a depăși un atacator determinat.



imagine

O modalitate mai bună este să utilizați mktemp programul (a nu se confunda cu mktemp funcția standard de bibliotecă) pentru a denumi și a crea fișierul temporar. The mk- temp programul acceptă un șablon ca argument care este folosit pentru a construi numele fișierului. Șablonul ar trebui să includă o serie de caractere „X”, care sunt înlocuite cu un număr corespunzător de litere și numere aleatorii. Cu cât seria de caractere „X” este mai lungă, cu atât seria de caractere aleatoare este mai lungă. Iată un exemplu:

tempfile=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)

Aceasta creează un fișier temporar și atribuie numele acestuia variabilei tempfile. Caracterele „X” din șablon sunt înlocuite cu litere și numere aleatorii, astfel încât numele final al fișierului (care, în acest exemplu, include și valoarea extinsă a parametrului special $$ pentru a obține PID) ar putea fi ceva de genul:

/tmp/foobar.6593.UOZuvM6654

Pentru scripturile care sunt executate de utilizatori obișnuiți, poate fi înțelept să evitați utilizarea / tmp director și creați un director pentru fișierele temporare în directorul principal al utilizatorului, cu o linie de cod ca aceasta:

[[ -d $HOME/tmp ]] || mkdir $HOME/tmp


Top OS Cloud Computing la OnWorks: