Workstation online OnWorks Linux e Windows

Logo

Hosting online gratuito per workstation

<Precedenti | Contenuti | Succ.>

Trappole

Nel Capitolo 10 abbiamo visto come i programmi possono rispondere ai segnali. Possiamo aggiungere questa funzionalità anche ai nostri script. Mentre gli script che abbiamo scritto finora non ne hanno avuto bisogno (perché hanno tempi di esecuzione molto brevi e non creano file temporanei), script più grandi e complessi potrebbero trarre vantaggio dall'avere una routine di gestione dei segnali.

Quando progettiamo uno script complesso e di grandi dimensioni, è importante considerare cosa succede se l'utente si disconnette o spegne il computer mentre lo script è in esecuzione. Quando si verifica un evento del genere, verrà inviato un segnale a tutti i processi interessati. A loro volta, i programmi che rappresentano tali processi possono eseguire azioni per garantire una terminazione corretta e ordinata del programma. Supponiamo, ad esempio, di aver scritto uno script che crea un file temporaneo durante la sua esecuzione. Nel corso di una buona progettazione, faremmo in modo che lo script elimini il file al termine del suo lavoro. Sarebbe anche opportuno che lo script eliminasse il file se ricevesse un segnale che indica che il programma sta per essere terminato prematuramente.

bash fornisce un meccanismo per questo scopo noto come trappolaLe trappole vengono implementate con il comando incorporato opportunamente denominato, trappola. trappola utilizza la seguente sintassi:

trappola segnale di argomento [segnale...]

where argomento è una stringa che verrà letta e trattata come un comando e segnale è la specifica di un segnale che attiverà l'esecuzione del comando interpretato.

Qui c'è un semplice esempio:



#! / Bin / bash


# trap-demo: demo semplice sulla gestione del segnale

#! / Bin / bash


# trap-demo: demo semplice sulla gestione del segnale


trap "echo 'Ti sto ignorando.'" SIGINT SIGTERM for i in {1..5}; do

echo "Iterazione $i di 5" sleep 5

fatto

trap "echo 'Ti sto ignorando.'" SIGINT SIGTERM for i in {1..5}; do

echo "Iterazione $i di 5" sleep 5

fatto


Questo script definisce una trappola che eseguirà un eco comando ogni volta che viene ricevuto il segnale SIG-INT o SIGTERM mentre lo script è in esecuzione. L'esecuzione del programma appare in questo modo quando l'utente tenta di interrompere lo script premendo Ctrl-c:


[io@linuxbox~]$ demo-trappola

Iterazione 1 di 5

Iterazione 2 di 5 Ti sto ignorando. Iterazione 3 di 5 Ti sto ignorando. Iterazione 4 di 5

Iterazione 5 di 5

[io@linuxbox~]$ demo-trappola

Iterazione 1 di 5

Iterazione 2 di 5 Ti sto ignorando. Iterazione 3 di 5 Ti sto ignorando. Iterazione 4 di 5

Iterazione 5 di 5


Come possiamo vedere, ogni volta che l'utente tenta di interrompere il programma, viene stampato il messaggio.

Costruire una stringa per formare una sequenza utile di comandi può essere complicato, quindi è prassi comune specificare una funzione shell come comando. In questo esempio, viene specificata una funzione shell separata per ogni segnale da gestire:



#! / Bin / bash

# trap-demo2: demo di semplice gestione del segnale exit_on_signal_SIGINT () {

echo "Script interrotto." 2>&1 exit 0

}


uscita_sul_segnale_SIGTERM () {

echo "Script terminato." 2>&1 exit 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM

#! / Bin / bash

# trap-demo2: demo di semplice gestione del segnale exit_on_signal_SIGINT () {

echo "Script interrotto." 2>&1 exit 0

}


uscita_sul_segnale_SIGTERM () {

echo "Script terminato." 2>&1 exit 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM



per i in {1..5}; fai

echo "Iterazione $i di 5" sleep 5

fatto


per i in {1..5}; fai

echo "Iterazione $i di 5" sleep 5

fatto


Questo script presenta due trappola comandi, uno per ogni segnale. Ogni trappola, a sua volta, specifica una funzione shell da eseguire quando viene ricevuto il segnale specifico. Notare l'inclusione di un exit comando in ciascuna delle funzioni di gestione del segnale. Senza un exit, lo script continuerebbe dopo aver completato la funzione.

Quando l'utente preme Ctrl-c durante l'esecuzione di questo script, i risultati appaiono come segue:



[io@linuxbox~]$ trappola-demo2

Iterazione 1 di 5

Iterazione 2 di 5 Script interrotto.

[io@linuxbox~]$ trappola-demo2

Iterazione 1 di 5

Iterazione 2 di 5 Script interrotto.


Immagine

File temporanei

Uno dei motivi per cui i gestori di segnale vengono inclusi negli script è quello di rimuovere i file temporanei che lo script potrebbe creare per contenere risultati intermedi durante l'esecuzione. C'è una sorta di arte nel nominare i file temporanei. Tradizionalmente, i programmi sui sistemi Unix-like creano i loro file temporanei nel / Tmp directory, una directory condivisa destinata a tali file. Tuttavia, poiché la directory è condivisa, ciò pone alcuni problemi di sicurezza, in particolare per i programmi eseguiti con privilegi di superutente. Oltre all'ovvio passaggio di impostare le autorizzazioni appropriate per i file esposti a tutti gli utenti del sistema, è importante assegnare ai file temporanei nomi di file non prevedibili. Questo evita un exploit noto come attacco di gara temporaneoUn modo per creare un nome non prevedibile (ma comunque descrittivo) è fare qualcosa del genere:

tempfile=/tmp/$(nome base $0).$$.$RANDOM

Verrà creato un nome file composto dal nome del programma, seguito dal suo ID di processo (PID), seguito da un numero intero casuale. Si noti, tuttavia, che $RAN- DOM La variabile shell restituisce solo un valore compreso tra 1 e 32767, che non è un intervallo molto ampio in termini informatici, quindi una singola istanza della variabile non è sufficiente per sconfiggere un aggressore determinato.



Immagine

Un modo migliore è usare il mktemp programma (da non confondere con il mktemp funzione della libreria standard) sia per nominare che per creare il file temporaneo. La mk-temp Il programma accetta un modello come argomento, utilizzato per costruire il nome del file. Il modello deve includere una serie di caratteri "X", che vengono sostituiti da un numero corrispondente di lettere e numeri casuali. Più lunga è la serie di caratteri "X", più lunga sarà la serie di caratteri casuali. Ecco un esempio:

file temporaneo=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)

Questo crea un file temporaneo e assegna il suo nome alla variabile filetempI caratteri "X" nel modello vengono sostituiti con lettere e numeri casuali in modo che il nome del file finale (che, in questo esempio, include anche il valore espanso del parametro speciale $$ per ottenere il PID) potrebbe essere qualcosa del tipo:

/tmp/foobar.6593.UOZuvM6654

Per gli script eseguiti da utenti regolari, potrebbe essere opportuno evitare l'uso di / Tmp directory e creare una directory per i file temporanei all'interno della directory home dell'utente, con una riga di codice come questa:

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


Il miglior sistema operativo cloud computing su OnWorks: