Datecp Script Revisited
I den første delen av Shell Script Guide har vi laget et skript som kopierte en fil til en sikkerhetskatalog etter å ha lagt til datoen til slutten av filnavnet.
Samuel Dionne-Riel påpekte i kommentarene at det er en mye bedre måte å håndtere våre variable referanser på.
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
vil fungere som ønsket så lenge de utvidede variablene ikke har mellomrom i dem. Hvis du ringer skriptet ditt på denne måten:
datecp 'my old name' 'my new name'
utvidelsen vil resultere i denne kommandoen:
cp my new name my old name.the_date
som faktisk har 6 argumenter.
For å løse dette problemet riktig må den siste linjen i skriptet være:
cp '$1' '$2.$date_formatted'
Som du kan se, endrer vi skriptets linje fra:
cp -iv $1 $2.$date_formatted
til:
cp -iv “$1” “$2”.$date_formatted
vil ta vare på dette problemet når du bruker skriptet på filer som har mellomrom i navnet. Samuel gjør også poenget at når du kopierer og limer koden fra dette nettstedet (eller Internett generelt), må du erstatte de riktige bindestreker og sitater for de "typografisk bedre" de som ofte erstatter dem. Vi vil også gjøre mer for å sikre at vår kode er mer kopi / lim inn vennlig.;-)
En annen kommentator, Myles Braithwaite, bestemte seg for å utvide vårt skript slik at datoen skulle vises før filtypen. Så i stedet for
tastyfile.mp3.07_14_11-12.34.56
vi ville få dette:
tastyfile.07_14_11-12.34.56.mp3
som ender opp med å være litt mer praktisk for de fleste brukere. Koden hans er tilgjengelig på hans GitHub-side. La oss se på hva han bruker for å trekke ut filnavnet.
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
Jeg har endret formateringen litt, men du kan se at Myles erklærer sin datoperiode i Linje 1. I linje 2 bruker han imidlertid "echo" -kommandoen med det første argumentet for manuset for å utdatere filens navn. Han bruker pipekommandoen til å ta utgangen og bruke den som input for neste del. Etter røret kaller Myles "awk" kommandoen, som er et kraftig mønster skanningsprogram. Ved å bruke -F-flagget, forteller han kommandoen at neste tegn (etter et mellomrom) er det som vil definere "feltavskiller". I dette tilfellet er det en periode.
Nå, awk se en fil kalt "tastyfile.mp3" som består av to felt: "tastyfile" og "mp3". Til slutt bruker han
‘{print $NF}’
for å vise det siste feltet. Hvis filen din har flere perioder - dermed gjør awk, se flere felt - det vil bare vise den siste, som er filtypen.
I linje 3 oppretter han en ny variabel for filens navn og bruker "basename" -kommandoen til å referere alt i $ 1 unntatt filtypen. Dette gjøres ved å bruke basenavn og gi den $ 1 som argument, og deretter legge til et mellomrom og filtypen. Filutvidelsen legges automatisk til på grunn av variabelen som refererer til linje 2. Hva dette ville gjøre er å ta
tastyfile.mp3
og slå den inn i
tastyfile
Så i siste linje, Myles sette sammen kommandoen som vil output alt i orden. Merk at det ikke er noen referanse til $ 2, et annet argument for skriptet. Dette bestemte skriptet vil kopiere filen til din nåværende katalog i stedet. Flott jobb Samuel og Myles!
Kjører skript og $ PATH
Vi nevner også i vår Grunnleggende artikkel at skript ikke har lov til å bli referert som kommandoer som standard. Det vil si at du må peke på skriptets bane for å kunne kjøre den:
./script
~/bin/script
Men ved å plassere skriptene i ~ / bin /, kan du bare skrive navnene deres hvor som helst for å få dem til å løpe.
Kommentarere brukte litt tid på å diskutere hvor riktig dette var, da ingen moderne Linux distro oppretter den katalogen som standard. Videre legger ingen heller den til $ PATH-variabelen som standard, hvilket er det som kreves for at skriptene skal bli kjørt som kommandoer. Jeg var litt forvirret fordi etter å ha sjekket min $ PATH-variabel, var kommentatorene riktige, men ringer skript fungerte fortsatt for meg. Jeg fant ut hvorfor: mange moderne Linux distros lager en spesiell fil i brukerens hjemmekatalog -.profile.
Gjenta kommandoer med løkker
La oss komme til et av de mest nyttige verktøyene i geek arsenalen for å håndtere repeterende oppgaver: sløyfer. I dag skal vi diskutere "for" looper.
Den grunnleggende oversikten over en forløp er som følger:
for VARIABLE in LIST; do command1 command2 … commandn done
VARIABLE kan være en hvilken som helst variabel, men oftest er små bokstaver "jeg" brukt etter konvensjon. LIST er en liste over elementer; Du kan angi flere elementer (skille dem med mellomrom), peke på en ekstern tekstfil, eller bruk en stjerne (*) for å angi hvilken som helst fil i gjeldende katalog. Kommandoene som er oppført er innrammet etter konvensjon, så det er lettere å se hekker - setter sløyfer i sløyfer (slik at du kan loop mens du slår).
Fordi lister bruker mellomrom som avgrensninger - det vil si et mellomrom betyr et trekk til neste element i listen - filer som har mellomrom i navnet er ikke så vennlige. For nå, la oss holde oss til å jobbe med filer uten mellomrom. La oss starte med et enkelt skript for å vise navnene på filene i gjeldende katalog. Opprett et nytt skript i din ~ / bin / folder med tittelen "loopscript". Hvis du ikke husker hvordan du gjør dette (inkludert merking av det som kjørbar og legger til hash bang hack), se vår bash scripting grunnleggende artikkel.
I den oppgir du følgende kode:
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
For sløyfer er ganske fantastiske. Nå kan du utføre batchfunksjoner på lister over filer. Du kan for eksempel kopiere alle skriptets argumenter til et zip-arkiv, flytte originaler til en annen mappe, og sikre automatisk kopiere den zip-filen til en ekstern datamaskin. Hvis du konfigurerer nøkkelfiler med SSH, trenger du ikke engang å skrive inn passordet ditt, og du kan til og med fortelle skriptet om å slette zip-filen etter opplasting av det!
Ved hjelp av forløser gjør det enkelt å gjøre en rekke handlinger for alle filer i en katalog. Du kan stable et bredt utvalg av kommandoer sammen og bruke argumenter veldig enkelt til å lage og flytte listen, og dette er bare toppen av isfjellet.
Bash scripters, har du noen forslag? Har du laget et nyttig skript som bruker sløyfer? Vil du dele tankene dine på serien? Legg igjen noen kommentarer og hjelp andre skripting nybegynnere ut!