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.
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
for i in *; do echo “$i” done
for i in $@; do zip archive “$i” done
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!