LA CAMPANA

C'è chi legge questa notizia prima di te.
Iscriviti per ricevere articoli freschi.
E-mail
Nome
Cognome
Come vuoi leggere The Bell
Niente spam

Che cos'è una shell e perché è necessaria

La shell dei comandi su qualsiasi sistema simile a unix, che include GNU / Linux, è un programma normale che viene eseguito sia in una console di testo (che viene utilizzata sempre meno) sia in un ambiente grafico - in una finestra dell'emulatore di terminale disponibile su qualsiasi sistema Linux .

Il suo compito è semplice e ovvio: accettare una linea (o linee) di input, analizzarle e, sulla base dei risultati di questa analisi, reagire di conseguenza - eseguire un comando, eseguire un programma, visualizzare un messaggio diagnostico, ecc.

In quasi tutti distribuzioni Linux bash è la shell predefinita per gli utenti (Bourne Again SHell è un'altra shell di comandi Burn; Steve Burn è l'autore della prima shell Unix - sh). In effetti, è diventata uno standard non ufficiale e un miglioramento per lei funzionalità continua continuamente. Esistono altre shell di comandi: tcsh (versione C-shell), ksh (Korn Shell), zsh, ecc. - ognuno ha i suoi vantaggi e svantaggi, così come i suoi gruppi di fan. Tuttavia, bash è più familiare alle grandi masse di utenti con diversi livelli di formazione, ecco perché ho optato per questo. Vale anche la pena notare che, indipendentemente dalle capacità possedute da varie conchiglie, sono tutte compatibili con il loro progenitore ideologico - Bourn Shell (sh). In altre parole, lo script scritto per sh funzionerà correttamente in qualsiasi shell moderna (il contrario, in generale, non è corretto).

Vantaggi della riga di comando

Potrebbe sorgere la domanda: perché preoccuparsi della riga di comando se esistono interfacce grafiche comode e belle? Ci sono molte ragioni per questo. Innanzitutto, non tutte le operazioni sono più convenienti e più veloci da eseguire utilizzando l'interfaccia grafica. In secondo luogo, ogni programma segue il principio fondamentale dei sistemi Unix: fare un lavoro ben definito e farlo bene. In altre parole, capisci sempre cosa succede quando esegui una particolare utility (se qualcosa non è del tutto chiaro, allora dovresti fare riferimento al manuale man). In terzo luogo, padroneggiando il team, provando le loro combinazioni e combinazioni dei loro parametri, l'utente impara il sistema, acquisendo preziosa esperienza pratica. È possibile accedere a strumenti efficaci come pipeline che consentono di organizzare una catena di comandi per l'elaborazione dei dati, strumenti di reindirizzamento input / output e inoltre, è possibile programmare direttamente nella shell dei comandi. Forse vale la pena soffermarsi sulla programmazione in modo più dettagliato, soprattutto perché molti script di sistema in Linux (ad esempio, script per l'avvio di servizi di sistema) sono scritti per la shell.

Shell come linguaggio di programmazione

Pertanto, la shell dei comandi può essere considerata come un linguaggio di programmazione e contemporaneamente come un runtime software. Naturalmente, questo linguaggio non è compilato, ma interpretato. Permette l'uso di variabili: sistema o il tuo. La sequenza di esecuzione dei comandi del programma viene modificata usando le condizioni che controllano i costrutti e selezionando l'opzione appropriata: if-then-else e case. Mentre, fino a quando e per i cicli automatizzano più azioni ripetute. È possibile combinare gruppi di comandi in blocchi logici. Puoi persino scrivere funzioni reali passando loro i parametri. Pertanto, ci sono tutti i segni e le caratteristiche di un linguaggio di programmazione completo. Proviamo a trarne doppio vantaggio: insieme all'apprendimento delle basi della programmazione, automatizziamo il nostro lavoro quotidiano.

Ciao mondo! Sistema di backup semplice

Sulla necessità di regolare prenota copia tutti conoscono i dati, ma gli utenti non hanno sempre tempo per questa noiosa operazione. La soluzione è semplice: organizza i backup automatici. Questa sarà la nostra prima attività di programmazione nella shell.

#! / bin / bash # # Backup di directory e file dalla directory home # Questo script di comando può essere eseguito automaticamente utilizzando cron # cd $ HOME se [! -d archives] quindi mkdir archives fi cur_date \u003d `date +% Y% m% d% H% M` se [$ # -eq 0]; quindi tar czf archive $ (cur_date) .tar.gz progetti bin altro tar czf archive $ (cur_date) .tar.gz $ * fi if [$? \u003d 0]; quindi mv archive $ (cur_date) .tar.gz $ HOME / archives echo "$ cur_date - Backup completato con successo." else echo "$ cur_date - ERROR durante il backup." fi

Qualsiasi script di comando (script - uno script, il cosiddetto programma shell) inizia con una riga identificativa in cui l'interprete dei comandi viene esplicitamente specificato con il percorso completo. Il percorso completo è un elenco sequenziale di tutte le directory, a partire dalla directory principale, che deve essere immessa per raggiungere il file di destinazione e, ovviamente, il nome di questo file. La registrazione del percorso completo è estremamente importante per identificare in modo univoco ciascun file nella gerarchia del file system.

Seguono quattro righe di commenti. Non appena la shell incontra il carattere "#", considera tutti i caratteri successivi come commenti e li ignora completamente fino alla fine della riga corrente. Pertanto, è possibile iniziare il commento non dall'inizio della riga, ma accompagnarli con qualsiasi comando.

Dopo i commenti c'è una riga vuota. Per la shell, non significa nulla e non viene intrapresa alcuna azione. Negli script, le righe vuote vengono generalmente inserite per rendere leggibile il codice.

Finalmente siamo arrivati \u200b\u200balla prima squadra "reale". Ti consente di cambiare la directory (Cambia directory), ad es. passa dalla directory corrente a un'altra, passata al comando come argomento. Nella maggior parte dei casi, la directory di destinazione viene specificata in modo esplicito, ad esempio progetti cd / tmp o cd, ma nel nostro caso viene utilizzata la variabile di sistema predefinita HOME - contiene il percorso completo della directory home dell'utente corrente, per conto del quale viene eseguito lo script di comando. Pertanto, ci liberiamo della necessità di apportare modifiche al codice ogni volta che cambiamo l'utente, poiché il comando restituisce chiunque alla sua directory personale. Il simbolo del dollaro "$" davanti al nome della variabile significa che è necessario estrarre il valore contenuto in questa variabile e sostituirlo nella riga di comando anziché nel nome. Va notato in particolare che nel linguaggio dei comandi le shell dei casi di lettere sono importanti, ad es. HOME, Home e Home sono tre variabili diverse. Per convenzione, le lettere maiuscole indicano i nomi delle variabili di sistema: HOME, PATH, EDITOR, ecc. Questo accordo non proibisce agli utenti di creare le proprie variabili con nomi in maiuscolo, ma perché complicare la propria vita violando le norme e le regole generalmente accettate? Inoltre, non è consigliabile modificare i valori delle variabili di sistema a meno che non sia assolutamente necessario. In generale, seguiamo una semplice regola: usiamo le variabili di sistema per la sola lettura e, se ne abbiamo bisogno, scriviamo il suo nome in lettere minuscole.

Il nostro primo comando potrebbe essere scritto più brevemente:

cd ~

Qui, il simbolo "~" indica anche la home directory dell'utente corrente. I veterani della riga di comando sono ancora più concisi:

CD

Il punto è che quando non viene fornito alcun argomento per il comando cd, si passa alla home directory.

Il prossimo passo è il classico design del software per verificare le condizioni e prendere una decisione appropriata. Lo schema generale è il seguente:

Se<условие> poi<одна или несколько команд> fi

L'ultima parola della costruzione (se nell'ordine inverso) funge da parentesi di chiusura, ovvero i limiti dell'elenco di comandi eseguiti se la condizione è vera. La presenza di fi è obbligatoria, anche se è elencata solo una squadra.

Per verificare la condizione, di norma, utilizzare il comando test o la sua forma alternativa di scrittura tra parentesi quadre. In altre parole, record

Se [! -d archivi] se prova! -d archivi

assolutamente equivalente. preferisco parentesi quadre, poiché definiscono più chiaramente i limiti della condizione da verificare. Le parentesi destra e sinistra devono essere separate dalla condizione da spazi.

I criteri per il controllo delle condizioni sono determinati da una varietà di bandiere. Il comando test ne riconosce un elenco molto ampio. Nel nostro esempio, è stato utilizzato il flag -d, che ci consente di verificare se il nome dato dopo il flag corrisponde a una directory reale esistente. I flag più comuni utilizzati quando si lavora con i file sono:

F: esiste un file regolare con il nome indicato;

R - se il diritto di leggere da esso è impostato per il file dato;

W - se il diritto di scrivere su di esso è impostato per il file dato;

X - se il diritto di eseguirlo è impostato per il file specificato;

S - se il file specificato ha una dimensione diversa da zero.

Nel nostro caso, la condizione si trova di fronte a un punto esclamativo che indica l'operazione di negazione logica, quindi il significato della condizione da testare diventa completamente opposto. Proviamo a scrivere il significato di questi comandi nel normale russo:

Se [! -d archives] Se la directory archives (nella directory corrente) non esiste, quindi iniziare a eseguire il blocco comandi: mkdir archives crea la directory archives (nella directory corrente) e termina il blocco comandi.

Come puoi vedere, tutto si è rivelato non così complicato. Un po 'di pratica e puoi facilmente leggere e creare tali disegni da solo. Il comando di creazione del catalogo è così ovvio che non sono necessarie ulteriori spiegazioni.

Nella riga successiva, creiamo la nostra variabile locale cur_date. Nella stragrande maggioranza dei casi, le variabili vengono create semplicemente assegnando un valore specifico, ad esempio:

ten \u003d 10 string \u003d "Questa è una riga di testo"

Ma nel nostro esempio, viene utilizzato un piccolo trucco. Si noti che dopo il segno di uguale - il simbolo di assegnazione - il comando è scritto tra virgolette. Questa forma di registrazione ci consente di assegnare alla variabile non la stringa stessa, ma il risultato della sua esecuzione. Ecco l'output del comando date, che restituisce la data e l'ora correnti nel formato definito dall'elenco dei parametri:

% Y - anno corrente in modulo completo, cioè quattro cifre (ad es. 2009);

% m - numero del mese corrente (ad esempio, 09 - per settembre);

% d - numero del giorno corrente;

% H: ora corrente nel formato 24 ore;

% M - minuto corrente.

Pertanto, se si esegue il comando

cur_date \u003d `data +% Y% m% d% H% M`

10 settembre 2009 alle 22:45, alla variabile cur_date verrà assegnato il valore di stringa "200909102245". Lo scopo di questo trucco è quello di creare un nome file di archivio unico e non duplicato. Se si intende eseguire diverse istanze del programma in un minuto, è possibile migliorare l'unicità dei nomi aggiungendo i secondi correnti. Come? Controlla il manuale dell'utilità date (man date) - non c'è nulla di complicato.

Prima di iniziare a creare un file di archivio, è necessario determinare quali directory verranno memorizzate in esso. Per una maggiore flessibilità, è possibile specificare un set di directory da archiviare per impostazione predefinita, ma fornire la possibilità di sostituire questo set con un elenco di directory, passato come argomento al nostro script di comando. Per questo, vengono utilizzate speciali variabili di shell: $ # - il numero di parametri passati allo script e $ * - tutti i parametri trasferiti scritti in un formato a riga singola.

if [$ # -eq 0]; poi

Controllando la condizione "se il numero di parametri passati è zero", quindi eseguire il comando seguente. Si noti che la parola chiave then può essere scritta nella riga delle condizioni, separandola dall'espressione condizionale con un punto e virgola.

tar czf archive $ (cur_date) .tar.gz bin progetti

Comando per creare un file di archivio e comprimere questo file. L'utilità tar stessa non esegue la compressione, ma raccoglie solo tutti i file e le directory specificati in un singolo file tar. Il primo flag è destinato a questo - c (create - per creare). La compressione viene eseguita da un programma esterno - qui è gzip, chiamato dal secondo flag - z. Se nel tuo sistema è installato un programma di compressione bzip2 più efficiente, puoi usarlo modificando il comando come segue:

tar cjf archive $ (cur_date) .tar.bz2 bin progetti

Il terzo flag f indica che segue il nome del file di archivio, quindi è sempre in coda nell'elenco dei flag. Si noti che durante la sostituzione, il nome della variabile è racchiuso tra parentesi graffe. Questo viene fatto per evidenziare esplicitamente la variabile nella linea che la circonda, eliminando così molti potenziali problemi. Le estensioni al file di archivio non vengono assegnate automaticamente, tu stesso aggiungi tutto ciò di cui hai bisogno. Come directory archiviate per impostazione predefinita, ho specificato progetti e bin, ma puoi scrivere qui i nomi delle tue directory più preziose.

La parola chiave else apre un ramo di esecuzione alternativo. I comandi di questo blocco iniziano a funzionare se il controllo della condizione dà il risultato "falso" (nel nostro esempio: "il numero di parametri passati è diverso da zero", ovvero l'utente ha specificato i nomi delle directory). In questo caso, il comando sarà simile al seguente:

tar czf archive $ (cur_date) .tar.gz $ *

Qui, le directory vengono sostituite per impostazione predefinita con una stringa di nomi di directory accettata dall'esterno. È possibile accettare ed elaborare singolarmente ogni parametro esterno, ma è più conveniente per noi passare l'intera stringa.

Alla fine del programma, viene eseguito un altro controllo. In ambienti unix, tutti i comandi restituiscono un codice di stato di completamento. Se il comando ha funzionato correttamente, restituisce il codice 0, altrimenti il \u200b\u200bcodice di completamento sarà diverso da zero. Per verificare il successo del precedente comando di archiviazione, utilizziamo un'altra variabile speciale, $ ?, che contiene sempre il valore del codice di completamento del comando più recente. Se nella variabile $? contiene 0, ad es. Il file di backup è stato creato correttamente, quindi lo spostiamo nella directory di archivio:

mv archive $ (cur_date) .tar.gz $ HOME / archivi

ed emettere il messaggio appropriato:

echo "$ cur_date - Backup completato con successo."

Se il controllo ha mostrato che il codice per completare l'operazione di archiviazione non è uguale a zero, viene visualizzato un messaggio di errore:

echo "$ cur_date - ERROR durante il backup."

Questo completa il lavoro del nostro team script.

Per verificare il funzionamento del nostro programma, è necessario salvare quanto sopra fonte in un file, ad esempio, con il nome bckp, e quindi per comodità renderlo eseguibile:

chmod 750 bckp

e corri:

./bckp

per eseguire il backup delle directory predefinite e

./bckp docs progs funziona

per creare una copia di backup delle directory elencate (specificare i nomi delle directory effettivamente presenti sul proprio sistema, altrimenti si riceverà un messaggio di errore).

È possibile posizionare il file bckp in una delle directory specificate nella variabile di sistema PATH. I posizionamenti più preferiti sono / usr / local / bin o $ HOME / bin, se ne hai. Successivamente, è possibile eseguire bckp come comando di sistema.

Come automatizzare le operazioni di backup pianificate

Qualche parola sull'automazione del backup. A tale scopo viene utilizzato lo scheduler di sistema cron, che legge le istruzioni di lavoro da un file crontab speciale. Per definire tali istruzioni, è necessario creare e modificare il file crontab usando il comando:

crontab -e

Le istruzioni sono scritte in un formato rigorosamente definito (i campi sono separati da spazi):

minuti ore day_month month day_week team

Una delle opzioni per la pianificazione delle operazioni di backup potrebbe essere simile alla seguente:

30 23 10,20,30 * * / usr / local / bin / bckp

Ciò significa che lo script di backup (deve essere specificato il percorso completo di questo file) verrà eseguito alle 23:30 del 10, 20 e 30 di ogni mese, indipendentemente dal giorno della settimana. (Gli asterischi indicano l'intero intervallo accettabile di valori, in questo caso: ogni mese nel 4 ° campo, ogni giorno della settimana nel 5 ° campo)

Se si preferisce eseguire il riepilogo per settimane e il sistema funziona 24 ore su 24, ha senso pianificare i backup in ore con un carico minimo:

0 5 * * 3.5 / usr / local / bin / bckp

Qui backup verrà creato alle 5:00 di mercoledì e venerdì di ogni mese (asterisco nel 4o campo), indipendentemente dal numero (asterisco nel 3o campo).

Puoi leggere tutte le complessità della pianificazione nel manuale di crontab man 5.

Sommario e conclusioni

Lo script di backup discusso in questo articolo ha proprietà funzionali modeste. Ma questo non era il suo compito principale, ma il lettore capiva cosa si potesse fare riga di comandoe non solo ha copiato ed eseguito il file batch proposto, ma si è interessato ad espandere le sue funzioni, impegnato nell'esplorazione delle immense possibilità fornite dalle shell dei comandi. E se qualcuno, dopo aver letto questo articolo, cerca di migliorare il codice fornito qui, o scrive la propria versione o implementa la sua idea indipendente, allora considererò che l'obiettivo principale è stato raggiunto.

Scarica risorse

static.content.url \u003d http: //www.site/developerworks/js/artrating/

ArticleID \u003d 458335

ArticleTitle \u003d Fondamenti di programmazione Shell

  • lezione

Nozioni di base di BASH. Parte 2.
Mi scuso per un ritardo così grande tra gli articoli, ma la sessione si fa sentire nel momento più inopportuno :)
Grazie a tutti per i commenti, le critiche e le aggiunte che sono state espresse nei commenti sull'articolo precedente.
Questa parte, come promesso, sarà dedicata ai cicli, alle operazioni matematiche e all'uso di comandi esterni.
Iniziamo.

Cicli. Ciclo for-in

L'operatore for-in viene utilizzato per accedere uno alla volta ai valori elencati nell'elenco. Ogni valore nell'elenco è assegnato a una variabile.
La sintassi è la seguente:
per variabile in value_list
fare
squadre
fatto

Considera un piccolo esempio:

#! / bin / bash
per i in 0 1 2 3 4 # alla variabile $ i assegneremo alternativamente valori da 0 a 4 inclusi
fare
echo "Il numero della console è $ i" \u003e\u003e / dev / pts / $ i # Scrive la riga "Il numero della console è $ i" nel file / dev / pts / $ i (file terminale virtuale)
fatto # loop over
uscita 0

Dopo aver eseguito l'esempio, una riga con il suo numero apparirà nelle prime 5 console virtuali (terminali). I valori dall'elenco vengono sostituiti uno alla volta nella variabile $ i e il ciclo funziona con il valore di questa variabile

Cicli. Mentre loop.

Il ciclo while è più complesso del ciclo for-in e viene utilizzato per ripetere i comandi fino a quando alcune espressioni sono vere (codice di ritorno \u003d 0).
La sintassi dell'operatore è la seguente:
mentre espressione o comando restituiscono un codice di ritorno
fare
squadre
fatto

Un esempio del funzionamento del ciclo è considerato nel seguente esempio:

#! / bin / bash
again \u003d yes # assegna nuovamente il valore "yes" alla variabile
while ["$ again" \u003d "yes"] # Eseguiremo un ciclo fino a quando $ again sarà uguale a "yes"
fare
echo "Inserisci un nome:"
leggi il nome
echo "Il nome che hai inserito è $ name"

Eco "Desideri continuare?"
leggi ancora
fatto
echo "Ciao ciao"


E ora il risultato della sceneggiatura:
[e-mail protetta]: ~ $ ./bash2_primer1.sh
Per favore inserisci un nome:
ite
Il nome che hai inserito è ite
Vuoi continuare?

Per favore inserisci un nome:
mihail
Il nome che hai inserito è mihail
Vuoi continuare?
no
Ciao ciao

Come puoi vedere, il loop viene eseguito fino a quando non introduciamo qualcosa di diverso da "yes". Tra do e done, puoi descrivere qualsiasi struttura, operatore, ecc., Tutti verranno eseguiti in un ciclo, ma dovresti fare attenzione con questo ciclo se esegui un comando al suo interno, senza cambiare la variabile di espressione, puoi entrare in un ciclo infinito.
Ora sulla condizione della verità. Dopo un po ', come nell'istruzione condizionale if-then-else, è possibile inserire qualsiasi espressione o comando che restituisca un codice di ritorno e il ciclo verrà eseguito fino a quando il codice di ritorno \u003d 0! L'operatore "[" è un analogo del comando test, che verifica la validità della condizione che gli è stata passata.

Considera un altro esempio, l'ho preso dal libro Advanced Bash Scripting. Mi è davvero piaciuto :), ma l'ho semplificato un po '. In questo esempio, introdurremo un altro tipo di loop UNTIL-DO.. Questo è quasi un analogo completo del ciclo WHILE-DO, solo alcune espressioni sono state eseguite finora.
Ecco un esempio:

#! / bin / bash
echo "Inserisci il numeratore:"
leggere il dividendo
echo "Inserisci il denominatore:"
leggi divisore

Dnd \u003d $ dividendo # cambieremo le variabili dividendo e divisore,
# salva la loro conoscenza in altre variabili, come loro siamo noi
# bisogno
dvs \u003d $ divisore
resto \u003d 1

Fino a ["$ remainder" -eq 0]
fare
lascia "resto \u003d dividendo% divisore"
dividendo \u003d $ divisore
divisore \u003d $ resto
fatto

Eco "GCD dei numeri $ dnd e $ dvs \u003d $ dividendo"


Il risultato dello script:
[e-mail protetta]: ~ $ ./bash2_primer3.sh
Inserisci il numeratore:
100
Inserisci il denominatore:
90
GCD dei numeri 100 e 90 \u003d 10

Operazioni matematiche

Lascia il comando.
Il comando let esegue operazioni aritmetiche su numeri e variabili.
Considera un piccolo esempio in cui eseguiamo alcuni calcoli sui numeri inseriti:
#! / bin / bash
echo "Inserisci un:"
leggi un
echo "Inserisci b:"
leggi b

Lascia che "c \u003d a + b" # aggiunta
echo "a + b \u003d $ c"
let "c \u003d a / b" # division
echo "a / b \u003d $ c"
lascia "c<<= 2" #сдвигает c на 2 разряда влево
echo "c dopo uno spostamento di 2 cifre: $ c"
let "c \u003d a% b" # trova il resto della divisione di a per b
echo "$ a / $ b. saldo: $ c"


Risultato dell'esecuzione:
[e-mail protetta]: ~ $ ./bash2_primer2.sh
Entrare in un:
123
Inserisci b:
12
a + b \u003d 135
a / b \u003d 10
c dopo uno spostamento di 2 cifre: 40
123/12 Saldo: 3

Bene, come puoi vedere, niente di complicato, l'elenco delle operazioni matematiche è standard:
+ - aggiunta
- - sottrazione
* - moltiplicazione
/ - divisione
** - esponenziazione
% - module (modulo division), resto della divisione
ti permette di usare abbreviazioni di comandi aritmetici, riducendo così il numero di variabili utilizzate. Ad esempio: a \u003d a + b è equivalente a a \u003d \u003d b, ecc.

Lavorare con programmi esterni durante la scrittura di script di shell

Innanzitutto, una piccola teoria utile.
Reindirizzamento dei flussi.
In bash (come molte altre shell) ci sono descrittori di file integrati: 0 (stdin), 1 (stdout), 2 (stderr).
stdout - Output standard. Ottiene tutto ciò che viene visualizzato dal programma
stdin - Input standard. Questo è tutto ciò che l'utente digita nella console
stderr - Output errore standard.
Per le operazioni con questi descrittori, ci sono caratteri speciali:\u003e (reindirizzamento dell'output),< (перенаправление ввода). Оперировать ими не сложно. Например:
reindirizzare l'output di cat / dev / random su / dev / null (operazione assolutamente inutile :))) o
scrivere il contenuto della directory corrente nel file di elenco (già più utile)
Se è necessario aggiungere al file (quando si utilizza "\u003e" viene sostituito), è necessario utilizzare "\u003e\u003e" anziché "\u003e"
dopo la richiesta di sudo per una password, verrà presa dal file my_password, come se fosse stato inserito dalla tastiera.
Se è necessario scrivere nel file solo errori che potrebbero essersi verificati durante il funzionamento del programma, è possibile utilizzare:
./program_with_error 2\u003e file_errore
il numero 2 prima di "\u003e" significa che devi reindirizzare tutto ciò che cade nella maniglia 2 (stderr).
Se devi forzare stderr a scrivere su stdout, puoi rintracciarlo. modo:
carattere "&" significa puntatore per gestire 1 (stdout)
(Per impostazione predefinita, stderr scrive sulla console su cui l'utente sta lavorando (scrive sul display in precedenza)).
2. Trasportatori.
La pipeline è uno strumento molto potente per lavorare con la console Bash. La sintassi è semplice:
team1 | comando 2 - significa che l'output del comando 1 verrà trasmesso all'ingresso del comando 2
Le pipeline possono essere raggruppate in catene e output utilizzando il reindirizzamento a un file, ad esempio:
ls -la | grep "hash" | sort\u003e sortilg_list
l'output del comando ls -la viene passato al comando grep, che seleziona tutte le righe contenenti la parola hash e passa il comando sort al comando sort, che scrive il risultato nel file sorting_list. Tutto è abbastanza chiaro e semplice.

Molto spesso, gli script Bash vengono utilizzati per automatizzare alcune operazioni di routine nella console, quindi a volte diventa necessario elaborare lo stdout di un comando e trasferirlo su stdin su un altro comando, mentre il risultato dell'esecuzione di un comando deve essere gestito in qualche modo. In questa sezione, cercherò di spiegare i principi di base del lavoro con comandi esterni all'interno dello script. Penso di aver dato abbastanza esempi e ora possiamo scrivere solo i punti principali.

1. Passare l'output a una variabile.
Per scrivere l'output di un comando in una variabile, è sufficiente racchiudere il comando tra virgolette, ad esempio
a \u003d `echo" qwerty "`
echo $ a

Risultato del lavoro: qwerty


Tuttavia, se si desidera scrivere un elenco di directory in una variabile, è necessario elaborare correttamente il risultato per inserire i dati nella variabile. Considera un piccolo esempio:
ELENCO \u003d `find / svn / -type d 2\u003e / dev / null | awk "(FS \u003d" / ") (stampa $ 4)" | ordina | uniq | tr "\\ n" "" `
per ONE_OF_LIST in $ LIST
fare
svnadmin hotcopy / svn / $ ONE_OF_LIST / svn / temp4backup / $ ONE_OF_LIST
fatto

Qui usiamo il ciclo for-do-done per archiviare tutte le directory nella cartella / svn / usando il comando svnadmin hotcopy (che nel nostro caso non ha importanza per nessuno, solo come esempio). Di grande interesse è la linea: LIST \u003d `find / svn / -type d 2\u003e / dev / null | awk "(FS \u003d" / ") (stampa $ 4)" | ordina | uniq | tr "\\ n" "" `In esso, alla variabile LIST è assegnata l'esecuzione del comando find elaborato dai comandi awk, sort, uniq, tr (non prenderemo in considerazione tutti questi comandi, poiché si tratta di un articolo separato). La variabile LIST conterrà i nomi di tutte le directory nella cartella / svn / situata sulla stessa riga (per cancellarla dal ciclo.

Come puoi vedere, tutto non è complicato, basta capire il principio e scrivere un paio di script. In conclusione, ti auguro buona fortuna nell'apprendimento di BASH e Linux in generale. Le critiche come al solito sono benvenute. Il prossimo articolo sarà probabilmente dedicato all'uso di programmi come sed, awk.

Degtyarev E.K. Shell: un interprete di comandi emessi dal terminale o da un file batch. esso programma regolare (ovvero non incluso nel core sistema operativo UNIX). Può essere sostituito da un altro o avere diversi. Le due versioni più famose sono: - Shell (versione UNIX 7) o Bourne Shell (dal nome dell'autore S.R. Bourne di Bell Labs); - C-Shell (versioni Berkley UNIX). Sono simili, ma ci sono alcune differenze: C-Shell è più potente in modalità dialogo, mentre Shell normale ha strutture di controllo più eleganti. Shell è un linguaggio di programmazione in quanto ha: - variabili; - strutture di controllo (come se); - subroutine (inclusi file batch); - trasferimento di parametri; - interrompere la gestione.

7.2. File di inizio sessione (file di accesso)

Indipendentemente dalla versione di Shell, quando si accede a UNIX, cerca un file di sessione con un nome predefinito da eseguire come file batch; - per Versione UNIX 7 questo è: .profile; - per C-Shell è: .login e / o .cshrc. In questo file vengono generalmente inseriti i seguenti comandi: - impostazione delle caratteristiche del terminale; - avvisi come chi, data; - installazione di directory per la ricerca di comandi (di solito: / bin, / usr / bin); - cambia la descrizione comando da $ a un altro personaggio, ecc.

7.3. Procedura di linguaggio shell

Questo è un file batch. Due modi per chiamarlo per l'esecuzione: 1. $ sh dothat (dove dothat è un file batch); 2. $ chmod 755 dothat (rendilo fattibile, ovvero -rwxr-xr-x) $ dothat. Dovresti conoscere l'ordine di ricerca delle directory dei comandi (per impostazione predefinita): - corrente; - sistema / cestino; - system / usr / bin. Pertanto, se il nome del file batch duplica il nome del comando nelle directory di sistema, quest'ultimo diventerà non disponibile (a meno che non si digiti il \u200b\u200bnome completo).

7.4. Variabili di shell

In Shell versione 7, una definizione di variabile contiene un nome e un valore: var \u003d value. Accesso alla variabile - per nome con un simbolo $ davanti: fruit \u003d apple (definizione); echo $ fruit (accesso); apple (risultato eco). Quindi una variabile è una stringa. La concatenazione di stringhe è possibile: $ fruit \u003d apple $ fruit \u003d pine $ fruit $ echo $ fruit ananas $ fruite \u003d apple $ wine \u003d $ (fruite) jack $ echo $ wine applejack $ Altri modi per impostare il valore variabile sono l'input o l'output del file dal comando (vedere la sezione 7.6), nonché assegnare i valori a una variabile - al parametro del ciclo for dall'elenco di valori specificato esplicitamente o per impostazione predefinita (vedere la sezione 7.9). La variabile può essere: 1) Parte del nome file completo: $ d / nomefile, dove $ d è la variabile (ad esempio, d \u003d / usr / bin). 2) Parte del comando: $ S \u003d "sort + 2n + 1 - 2" (gli spazi richiedono virgolette "") $ $ S tennis / lpr $ $ S basket / lpr $ $ S pingpong / lpr $ Tuttavia, all'interno del valore per i comandi non possono essere caratteri |,\u003e,

7.5. Variabili predefinite della shell

Alcuni di essi possono solo essere letti. Il più comune: HOME - la directory "home" dell'utente; funge da argomento predefinito per cd; PERCORSO - molte directory in cui UNIX cerca i comandi; PS1 - il suggerimento principale (stringa) del sistema (per v.7 - $). La modifica di PS1 (suggerimenti) viene in genere eseguita nel file di accesso, ad esempio: PS1 \u003d? o PS1 \u003d "?" (con uno spazio, che è più conveniente). Cambia PERCORSO: $ echo $ PERCORSO - vedi; : / bin: / usr / bin - valore PATH; $ cd - "home"; $ mkdir bin - nuova directory; $ echo $ HOME - vedi; / users / maryann - directory corrente; $ PATH \u003d: $ HOME / bin: $ PATH - modifica del PERCORSO; $ echo $ PERCORSO - vedi; : / users / maryann / bin: / bin: / usr / bin - nuovo valore PATH.

7.6. Impostazione della variabile Shell con output del comando

Esempio 1: $ now \u003d `date` (dove`` sono le virgolette precedenti) $ echo $ now dom 14 feb 12:00:01 PST 1985 $ Esempio 2: (ottenere il valore di una variabile da un file): $ menu \u003d` cibo per gatti` $ echo $ menu cheddar di mele chardonnay (i ritorni a capo vengono sostituiti con spazi).

7.7. Variabili della shell - argomenti della procedura

Questo è un tipo speciale di variabile chiamata numero. Esempio: $ dothis uva mele pere (procedura). Quindi i parametri posizionali (argomenti) di questo comando sono disponibili per nome: $ 1 \u003d `uva` $ 2 \u003d` mele` $ 3 \u003d `pere`, ecc. fino a $ 9. Tuttavia, esiste un comando shift che sposta i nomi sul resto degli argomenti se ce ne sono più di 9 (finestra di larghezza 9). Un altro modo per ottenere tutti gli argomenti (anche se ce ne sono più di 9): $ *, che equivale a $ 1 $ 2 ... Il numero di argomenti è assegnato a un'altra variabile: $ # (sharp). Infine, il nome della procedura è $ 0; la variabile $ 0 non viene presa in considerazione nel calcolo di $ #.

7.8. Operatori strutturali shell

Oltre alle procedure, il linguaggio Shell ha operatori strutturali come "if-else" e "while-do". La programmazione della shell, oltre alle procedure di scrittura, viene utilizzata per: - testare l'algoritmo prima di codificarlo nei linguaggi C o FORTRAN-77 (nessuna compilazione, collegamento, caricamento, debug semplice); - insegnare i principi della programmazione di non programmatori.

7.9. Per operatore ad anello

Lascia che ci sia un file batch makelist (procedura) $ cat makelist sort +1 -2 persone | tr -d -9 | pr -h Distribuzione | LPR. Se invece di un singolo file di persone ce ne sono diversi, ad esempio: adminpepe, hardpeople, softpeople, ..., è necessario ripetere la procedura con file diversi. Questo è possibile utilizzando l'istruzione for. Sintassi: for in done done Le parole chiave per, do, done sono scritte dall'inizio della riga. Esempio (modifica procedura makelist) per file in adminpeople, hardpeople, softpeople do Ordina +1 -2 $ file | tr ... | fatto. È possibile utilizzare i metacaratteri Shell nell'elenco dei valori. Esempio: per file in * persone (per tutti i nomi che terminano in persone) do ... done. Se in viene omesso, per impostazione predefinita l'elenco di argomenti della procedura che contiene il ciclo viene preso come elenco di valori e se il ciclo non è nella procedura, quindi l'elenco dei parametri della riga di comando (ovvero, il comando funge da procedura). Esempio: per il file do ... done La stessa cosa verrà fatta per chiamare gli amministratori di makelist hardpeople softpeople.

7.10. Dichiarazione condizionale se

Usiamo nomi di variabili che rappresentano i valori dei parametri della procedura: ordina +1 -2 $ 1 | tr ... | lpr Esempio di chiamata non valida: makelist (senza parametri), dove $ 1 non è definito. Puoi correggere l'errore controllando il numero di argomenti - il valore della variabile $ # usando l'operatore if -. Esempio: (procedura makelist modificata): se test $ # -eq 0 allora echo "Devi dare un nome file" esci 1 altrimenti ordina +1 -2 $ 1 | tr ... | lpr fi Qui test e exit sono i test (vedi sezione 7.11) e i comandi exit. Pertanto, la sintassi di if: if; poi; Le parole chiave if, then, else e fi sono scritte dall'inizio della riga. L'esecuzione corretta della procedura indica che restituisce true \u003d 0 (zero) (errore: il valore restituito non è 0). L'istruzione exit 1 imposta il valore restituito 1 per makelist non riesce e termina la procedura. Annidato se possibile. Per altro se esiste un'abbreviazione elif, che contemporaneamente abbrevia fi.

7.11. Comando di prova

Non fa parte di Shell, ma viene utilizzato all'interno delle procedure Shell. Esistono tre tipi di controlli: - valutazione dei valori numerici; - valutazione del tipo di file; - linee di punteggio. Ogni tipo ha le sue primitive (operazioni op). Per i numeri, la sintassi è: N op M, dove N, M sono numeri o variabili numeriche; op accetta i valori: -eq, -ne, gt, -lt, -ge, -le (con il solito significato, come, ad esempio, in FORTRAN). La sintassi per il file è: op nomefile, dove op prende i valori: -s (il file esiste e non è vuoto); -f (file, non directory); -d (directory-file (directory); -w (file per la scrittura); -r (file per la lettura) Per le stringhe, la sintassi è: S op R, dove S, R sono stringhe o variabili stringa, oppure op1 S op accetta valori : \u003d (equivalenza) ;! \u003d (non equivalenza); op1 assume i valori: -z (stringa di lunghezza zero); -n (non lunghezza zero della stringa). Infine, è possibile combinare diversi controlli di tipi diversi con le operazioni logiche -a ( AND) e -o (OR) Esempi: $ if test -w $ 2 -a -r S1\u003e quindi cat $ 1 \u003e\u003e $ 2\u003e altrimenti echo "impossibile aggiungere"\u003e fi $ In alcune versioni del sistema operativo UNIX, invece del comando test, parentesi quadre, ovvero se [...] anziché if test ....

7.12. Istruzione loop while

Sintassi: while do done Se il "comando" ha esito positivo, eseguire i "comandi" terminati parola chiave fatto. Esempio: se test $ # -eq 0 allora echo "Uso: $ 0 file ..."\u003e & 2 esci da fi mentre test $ # -gt 0 esegui test -s $ 1 quindi echo "nessun file $ 1"\u003e & 2 ordina + + 1 - 2 $ 1 | tr -d ... (procedure) fi shift (* renumber argomenti *) done Le procedure vengono eseguite su tutti gli argomenti.

7.13. Dichiarazione fino a

Inverte la condizione di ripetizione rispetto a mentre Sintassi: fino a quando non viene eseguito Finché il "comando" non riesce, eseguire i comandi terminati dalla parola completata. Esempio: se test S # -eq 0 allora echo "Usa $ 0 file ..."\u003e & 2 esci da fi fino a test S # -eq 0 fai se test -s $ 1 allora echo "nessun file $ 1"\u003e & 2 altro ordina +1 - 2 $ 1 | tr -d ... (procedura) fi shift (argomento shift) done Esegue lo stesso di quello precedente.

7.14. Dichiarazione di selezione del caso

Sintassi: case in string1) ;; string2) ;; string3) ... ecc. ... esac Esempio: lascia che la procedura abbia l'opzione -t, che può essere servita come primo parametro: ................. insieme \u003d nessun caso $ 1 in -t) insieme \u003d sì cambio ;; -?) echo "$ 0: nessuna opzione $ 1" uscita ;; esac se test $ together \u003d yes allora ordina ... fi dove? - metacarattere (se -?, cioè un'opzione "diversa", diversa da -t, quindi un errore). È possibile utilizzare tutti i metacaratteri di Shell, inclusi?, *, [-]. È facile aggiungere (nell'esempio) altre opzioni semplicemente estendendo il caso.

7.15. Utilizzo di file temporanei nella directory / tmp

Questa è una directory speciale in cui tutti i file sono scrivibili da tutti gli utenti. Se una procedura per la creazione di un file temporaneo viene utilizzata da più utenti, è necessario garantire l'univocità dei nomi dei file creati. Il metodo standard è il nome del file temporaneo $ 0 $$, dove $ 0 è il nome della procedura e $$ è la variabile standard uguale al numero di identificazione univoco del processo che esegue il comando corrente. Sebbene l'amministratore elimini periodicamente i file temporanei in / tmp, è buona norma eliminarli esplicitamente dopo l'uso.

7.16. Commenti nelle procedure

Iniziano con due punti:, che è considerato un comando , e il testo del commento è il suo argomento. Per impedire a Shell di interpretare i metacaratteri ($, *, ecc.), Si consiglia di racchiudere il testo del commento tra virgolette singole. Su alcune versioni di UNIX, una nota inizia con un #.

7.17. Esempio di procedura

: "Questa procedura funziona con file contenenti i nomi": "e numeri di telefono": "li ordina insieme o separatamente e stampa il risultato su uno schermo": "o su una stampante": "Tasti di procedura:": "- t (insieme) - unisci e ordina tutti i file insieme ":" - p (stampante) - stampa i file sulla stampante "se test $ # - eq 0 quindi echo" Utilizzo: file $ 0 ... "\u003e & 2 esci fi insieme \u003d no print \u003d no mentre test $ # -gt 0 fa $ 1 in -t) insieme \u003d yes shift ;; -p) print \u003d yes maiusc ;; -?) echo "$ 0: nessuna opzione $ 1" uscita ;; *) se test $ together \u003d yes allora ordina -u +1 -2 $ 1 | tr ...\u003e / tmp / $ 0 $$ se $ stampa \u003d no, quindi cat / tmp / $ 0 $$ altrimenti lpr -c / tmp / $ 0 $$ fi rm / tmp / $ 0 $$ uscita altro se test -s $ 1, quindi echo "nessun file $ 1"\u003e & 2 altro ordinamento +1 -2 $ 1 | tr ...\u003e / tmp / $ 0 $$ se $ stampa \u003d no, quindi cat / tmp / $ 0 $$ altrimenti lpr -c / tmp / $ 0 $$ fi rm / tmp / $ 0 $$ fi shift fi ;; esac fatto. La procedura controlla il numero di parametri $ # e, se è zero, termina. Altrimenti, elabora i parametri (case case). Una chiave (un carattere preceduto da un segno meno) o un nome di file (una stringa rappresentata da un metacarattere *) può fungere da parametro. Se la chiave è diversa da quella valida (metacarattere? È diversa da te p), la procedura termina. In caso contrario, a seconda della presenza dei tasti t e p, le azioni vengono eseguite come indicato nel commento all'inizio della procedura.

7.18. Interrompere la gestione nelle procedure

Se durante la procedura viene ricevuto un segnale di interruzione (ad esempio dal tasto BREAK o DEL), tutti i file temporanei creati rimarranno non eliminati (fino a quando l'amministratore non lo farà) a causa della conclusione immediata del processo. Soluzione migliore L'operatore trap è l'elaborazione degli interrupt all'interno di una procedura: Sintassi: segnali "argomenti comando" trap ... Le virgolette formano il primo argomento di diversi comandi separati da punti e virgola. Verranno eseguiti se c'è un interrupt indicato dagli argomenti dei segnali (numeri interi): 2 - quando si interrompe il processo; 1 - se si è "congelati" (disconnesso dal sistema), ecc. Un esempio (sviluppo del precedente): case $ 1 in ..... *) trap "rm / tmp / *; exit" 2 1 (eliminazione di file temporanei) se test -s $ 1 .............. rm / tmp / * Sarebbe meglio: trap "rm / tmp / *\u003e / dev / null; exit" 2 1 poiché l'interruzione può avvenire prima come viene creato il file / tmp / $ 0 $$ e un messaggio di allarme su questo caso viene inviato al dispositivo null.

7.19. Aritmetica: expr

Il comando expr calcola il valore dell'espressione fornita come argomento e invia il risultato all'output standard. L'applicazione più interessante è eseguire operazioni sulle variabili del linguaggio Shell. Esempio di somma di 3 numeri: $ cat sum3 expr $ 1 + $ 2 + $ 3 $ chmod 755 sum3 $ sum3 13 49 2 64 $ Esempio di uso diretto del comando: $ expr 13 + 49 + 2 + 64 + 1 129 $ I seguenti operatori aritmetici possono essere utilizzati in expr - ry: +, -, *, /,% (saldo). Tutti gli operandi e le operazioni devono essere separati da spazi. Si noti che il segno di moltiplicazione deve essere racchiuso tra virgolette (singole o doppie), ad esempio: "*", poiché il carattere * ha un significato speciale in Shell. Un esempio più complesso di expr in una procedura (snippet): num \u003d "wc -l

7.20. Procedure di debug Shell

Esistono tre strumenti per le procedure di debug. 1) Inserimento dei comandi echo nel corpo della procedura per l'emissione di messaggi che rappresentano il percorso della procedura. 2) L'opzione -v (verbose \u003d verbose) nel comando Shell stampa il comando sullo schermo prima di eseguirlo. 3) L'opzione -x (esegui) nel comando Shell stampa il comando sullo schermo mentre viene eseguito con tutte le variabili sostituite dai loro valori; Questo è lo strumento più potente.

LA CAMPANA

C'è chi legge questa notizia prima di te.
Iscriviti per ricevere articoli freschi.
E-mail
Nome
Cognome
Come vuoi leggere The Bell
Niente spam