The Beginner's Guide to Shell Scripting 2: For Loops

Sommario:

The Beginner's Guide to Shell Scripting 2: For Loops
The Beginner's Guide to Shell Scripting 2: For Loops

Video: The Beginner's Guide to Shell Scripting 2: For Loops

Video: The Beginner's Guide to Shell Scripting 2: For Loops
Video: L'acqua nel radiatore cala? Sei ancora in tempo... Fai questi controlli - YouTube 2024, Aprile
Anonim
Se vuoi creare il tuo cred di geek, unisciti a noi per la seconda parte della nostra serie di script di shell. Abbiamo alcune correzioni, alcuni miglioramenti alla sceneggiatura della scorsa settimana e una guida sul looping per chi non lo sapesse.
Se vuoi creare il tuo cred di geek, unisciti a noi per la seconda parte della nostra serie di script di shell. Abbiamo alcune correzioni, alcuni miglioramenti alla sceneggiatura della scorsa settimana e una guida sul looping per chi non lo sapesse.

Lo script datecp Revisited

Nella prima parte della nostra guida allo scripting della shell, abbiamo creato uno script che copiava un file in una directory di backup dopo aver aggiunto la data alla fine del nome file.

Samuel Dionne-Riel ha sottolineato nei commenti che c'è un modo molto migliore per gestire i nostri riferimenti variabili.

Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,

cp $1 $2.$date_formatted

funzionerà come previsto purché le variabili espanse non contengano spazi in esse. Se chiami il tuo script in questo modo:

datecp 'my old name' 'my new name'

l'espansione darà come risultato questo comando:

cp my new name my old name.the_date

che in realtà ha 6 argomenti.

Per risolvere correttamente questo problema, l'ultima riga dello script dovrebbe essere:

cp '$1' '$2.$date_formatted'

Come puoi vedere, cambiando la linea del nostro script da:

cp -iv $1 $2.$date_formatted

a:

cp -iv “$1” “$2”.$date_formatted

si prenderà cura di questo problema quando si utilizza lo script su file che hanno spazi nel nome. Samuel sottolinea anche che quando si copia e incolla il codice da questo sito (o da internet in generale) si deve assolutamente sostituire i trattini e le virgolette corretti per quelli "tipograficamente migliori" che spesso li sostituiscono. Faremo anche di più per assicurarci che il nostro codice sia più adatto alla copia / incolla.;-)

Un altro commentatore, Myles Braithwaite, ha deciso di espandere il nostro script in modo che la data fosse visualizzata prima dell'estensione del file. Quindi invece di

tastyfile.mp3.07_14_11-12.34.56

otterremmo questo:

tastyfile.07_14_11-12.34.56.mp3

che finisce per essere un po 'più conveniente per la maggior parte degli utenti. Il suo codice è disponibile nella sua pagina GitHub. Diamo un'occhiata a ciò che usa per separare il nome del file.

date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F. ‘{print $NF}’) file_name=$(basename $1.$file_extension)

cp -iv $1 $file_name-$date_formatted.$file_extension

Ho modificato la formattazione un po ', ma puoi vedere che Myles dichiara la sua funzione di data nella Linea 1. Nella Linea 2, tuttavia, usa il comando "echo" con il primo argomento dello script per produrre il nome del file. Usa il comando pipe per prendere quell'output e usarlo come input per la parte successiva. Dopo la pipe, Myles chiama il comando "awk", che è un potente programma di scansione dei pattern. Usando il flag -F, sta dicendo al comando che il prossimo carattere (dopo uno spazio) è ciò che definirà il "separatore di campo". In questo caso, questo è un periodo.

Ora, awk vede un file chiamato "tastyfile.mp3" come composto da due campi: "tastyfile" e "mp3". Infine, usa

‘{print $NF}’

per visualizzare l'ultimo campo. Nel caso in cui il tuo file abbia più periodi - quindi facendo awk vedere più campi - verrà visualizzato solo l'ultimo, che è l'estensione del file.

Nella riga 3, crea una nuova variabile per il nome del file e usa il comando "basename" per fare riferimento a tutto in $ 1 tranne l'estensione del file. Questo viene fatto usando basename e dandogli $ 1 come argomento, quindi aggiungendo uno spazio e l'estensione del file. L'estensione del file viene aggiunta automaticamente a causa della variabile che fa riferimento alla Linea 2. Ciò che questo dovrebbe fare è prendere

tastyfile.mp3

e trasformalo in

tastyfile

Poi nell'ultima riga, Myles metterà insieme il comando che produrrà tutto in ordine. Si noti che non vi è alcun riferimento a $ 2, un secondo argomento per lo script. Questo particolare script copierà il file nella directory corrente. Ottimo lavoro Samuel e Myles!

Esecuzione di script e $ PERCORSO

Nel nostro articolo Nozioni di base, citiamo anche che agli script non è consentito il riferimento come comandi per impostazione predefinita. Cioè, devi indicare il percorso dello script per eseguirlo:

./script

~/bin/script

Ma, inserendo i tuoi script in ~ / bin /, puoi semplicemente digitare i loro nomi da qualsiasi luogo per farli funzionare.

I commentatori hanno passato un po 'di tempo a discutere di quanto questo fosse corretto, in quanto nessuna distro Linux moderna crea quella directory per impostazione predefinita. Inoltre, nessuno lo aggiunge alla variabile $ PATH per impostazione predefinita, che è ciò che è necessario affinché gli script possano essere eseguiti come comandi. Ero un po 'perplesso perché dopo aver controllato la mia variabile $ PATH, i commentatori avevano ragione, ma chiamare script funzionava ancora per me. Ho scoperto perché: molte distribuzioni Linux moderne creano un file speciale nella directory home dell'utente -.profile.

Questo file viene letto da bash (a meno che.bash profile sia presente nella home directory dell'utente) e in fondo, c'è una sezione che aggiunge la cartella ~ / bin / alla variabile $ PATH, se esiste. Quindi, quel mistero è chiarito. Per il resto della serie, continuerò a inserire script nella directory ~ / bin / perché sono script utente e dovrebbero essere in grado di essere eseguiti dagli utenti. E, sembra che non abbiamo davvero bisogno di incasinare la variabile $ PATH a mano per far funzionare le cose.
Questo file viene letto da bash (a meno che.bash profile sia presente nella home directory dell'utente) e in fondo, c'è una sezione che aggiunge la cartella ~ / bin / alla variabile $ PATH, se esiste. Quindi, quel mistero è chiarito. Per il resto della serie, continuerò a inserire script nella directory ~ / bin / perché sono script utente e dovrebbero essere in grado di essere eseguiti dagli utenti. E, sembra che non abbiamo davvero bisogno di incasinare la variabile $ PATH a mano per far funzionare le cose.

Ripetizione dei comandi con cicli

Andiamo a uno degli strumenti più utili nell'arsenale dei geek per affrontare i compiti ripetitivi: loops. Oggi parleremo di "for" loop.

La struttura di base di un ciclo for è la seguente:

for VARIABLE in LIST; do command1 command2 … commandn done

VARIABLE può essere qualsiasi variabile, sebbene la maggior parte delle volte il "i" minuscolo sia usato per convenzione. LIST è un elenco di elementi; è possibile specificare più elementi (separandoli per uno spazio), puntare a un file di testo esterno o utilizzare un asterisco (*) per indicare qualsiasi file nella directory corrente. I comandi elencati sono rientrati per convenzione, quindi è più semplice vedere l'annidamento - mettere i loop nei loop (in modo da poter eseguire il loop durante il ciclo).

Poiché gli elenchi utilizzano spazi come delimitatori, ovvero uno spazio indica un passaggio all'elemento successivo nell'elenco, i file che contengono spazi nel nome non sono molto intuitivi. Per ora, continuiamo a lavorare con file senza spazi. Iniziamo con un semplice script per visualizzare i nomi dei file nella directory corrente. Crea un nuovo script nella tua cartella ~ / bin / intitolata "loopscript". Se non ricordi come farlo (includendolo come eseguibile e aggiungendo hash bang hack) fai riferimento al nostro articolo sulle basi di scripting bash.

In esso, inserisci il seguente codice:

for i in item1 item2 item3 item4 item5 item6; do echo “$i” done

Quando si esegue lo script, è necessario ottenere tali elementi di elenco come output.
Quando si esegue lo script, è necessario ottenere tali elementi di elenco come output.
Abbastanza semplice, vero? Vediamo cosa succede se cambiamo le cose un po '. Cambia il tuo script così dice questo:
Abbastanza semplice, vero? Vediamo cosa succede se cambiamo le cose un po '. Cambia il tuo script così dice questo:

for i in *; do echo “$i” done

Quando si esegue questo script in una cartella, si dovrebbe ottenere un elenco di file che contiene come output.
Quando si esegue questo script in una cartella, si dovrebbe ottenere un elenco di file che contiene come output.
Ora, cambiamo il comando echo in qualcosa di più utile, ad esempio il comando zip. Vale a dire, aggiungeremo i file in un archivio. E, prendiamo alcuni argomenti nel mix!
Ora, cambiamo il comando echo in qualcosa di più utile, ad esempio il comando zip. Vale a dire, aggiungeremo i file in un archivio. E, prendiamo alcuni argomenti nel mix!

for i in $@; do zip archive “$i” done

C'è qualcosa di nuovo! "$ @" È una scorciatoia per "$ 1 $ 2 $ 3 … $ n". In altre parole, è l'elenco completo di tutti gli argomenti specificati. Ora, guarda cosa succede quando eseguo lo script con diversi file di input.
C'è qualcosa di nuovo! "$ @" È una scorciatoia per "$ 1 $ 2 $ 3 … $ n". In altre parole, è l'elenco completo di tutti gli argomenti specificati. Ora, guarda cosa succede quando eseguo lo script con diversi file di input.
Puoi vedere quali file sono nella mia cartella. Ho eseguito il comando con sei argomenti e ogni file è stato aggiunto a un archivio zippato denominato "archive.zip". Facile, giusto?
Puoi vedere quali file sono nella mia cartella. Ho eseguito il comando con sei argomenti e ogni file è stato aggiunto a un archivio zippato denominato "archive.zip". Facile, giusto?

Per i loop sono piuttosto meravigliosi. Ora puoi eseguire funzioni batch su elenchi di file. Ad esempio, è possibile copiare tutti gli argomenti del proprio script in un archivio zippato, spostare gli originali in una cartella diversa e proteggere automaticamente la copia del file zip su un computer remoto. Se si configurano i file chiave con SSH, non è nemmeno necessario inserire la password e si può persino dire allo script di eliminare il file zip dopo averlo caricato!

L'utilizzo di for-loops facilita l'esecuzione di numerose azioni per tutti i file in una directory. È possibile impilare una vasta gamma di comandi insieme e utilizzare gli argomenti in modo molto semplice per creare una lista al volo, e questa è solo la punta dell'iceberg.

Script di Bash, hai qualche suggerimento? Hai realizzato uno script utile che utilizza i loop? Vuoi condividere i tuoi pensieri sulla serie? Lascia alcuni commenti e aiuta altri nuovi principianti di script!

Consigliato: