Homepage » come » La Guida per principianti di Shell Scripting 2 For Loops

    La Guida per principianti di Shell Scripting 2 For Loops

    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.

    Gli argomenti sono separati dallo spazio nella shell bash, verrà tokenize quando c'è uno spazio nel comando espanso risultante. Nella tua sceneggiatura, 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 il mio nuovo nome il mio vecchio nome.la_data che in realtà ha 6 argomenti.

    Per risolvere correttamente questo problema, l'ultima riga dello script dovrebbe essere: cp "$ 1" "$ 2. $ date_formattato"

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

    cp -iv $ 1 $ 2. $ date_formattato

    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 = $ (data +% Y-% m-% d_% H.% M% S)
    file_extension = $ (echo "$ 1" | awk -F. 'print $ NF')
    file_name = $ (basename $ 1. $ file_extension)

    cp -iv $ 1 $ nome_file- $ data_formattato. $ estensione_file

    Ho modificato la formattazione un po ', ma puoi vedere che Myles dichiara la sua funzione data nella riga 1. Nella riga 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

    Quindi, 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 fosse corretto, dal momento che nessuna distro Linux moderna crea quella directory di default. 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 il motivo: molte moderne distribuzioni Linux 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 posizionare gli 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:

    per VARIABLE in LIST; fare
    command1
    comando2
    ...
    commandn
    fatto

    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 che tu possa fare il loop mentre fai il loop).

    Poiché gli elenchi utilizzano gli 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 fare questo (includendolo come eseguibile e aggiungendo hash bang hack) fai riferimento al nostro articolo sulle basi di scripting bash.

    In esso, inserisci il seguente codice:

    per i in item1 item2 item3 item4 item5 item6; fare
    echo "$ i"
    fatto

    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:

    per io in *; fare
    echo "$ i"
    fatto

    Quando si esegue questo script in una cartella, è necessario 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, otteniamo alcuni argomenti nel mix!

    per i in $ @; fare
    archivio zip "$ i"
    fatto

    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?

    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ò anche 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 e utilizzare gli argomenti in modo molto semplice per creare una lista e 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 gli altri newbies dello scripting!