Hjemmeside » hvordan » Nybegynners Guide til Shell Scripting 2 For Loops

    Nybegynners Guide til Shell Scripting 2 For Loops

    Hvis du vil bygge opp geekkreditten din, kan du bli med på den andre avgiften i vår skriptskriptserie. Vi har noen rettelser, noen forbedringer i forrige ukes skript, og en veiledning om looping for uinitiert.

    Datecp Script Revisited

    I den første delen av Shell Skriptguide 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å.

    Argumenter er romavskilt i bash-skallet, det vil tilkjenne når det er plass i den resulterende utvidede kommandoen. I skriptet ditt, 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 "mitt gamle navn" "mitt nye navn" utvidelsen vil resultere i denne kommandoen: cp mitt nye navn mitt gamle navn.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 kommenterer, 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 med å være litt mer praktisk for de fleste brukere. Hans kode er tilgjengelig på sin GitHub-side. La oss se på hva han bruker for å trekke ut filnavnet.

    date_formatted = $ (dato +% Y-% m-% d_% H.% M% S)
    file_extension = $ (ekko "$ 1" | awk -F. 'print $ NF')
    file_name = $ (basenavn $ 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 datoen sin 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 utdataene 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 filnavnet 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:

    ./manus

    ~ / 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 riktig, men ringer skript fungerte fortsatt for meg. Jeg fant ut hvorfor: mange moderne Linux distros lager en spesiell fil i brukerens hjemmekatalog - .profile.

    Denne filen leses av bash (med mindre .bash_profile er til stede i brukerens hjemmekatalog) og nederst er det en del som legger til ~ / bin / mappen til $ PATH-variabelen hvis den eksisterer. Så, det mysteriet er oppklaret. For resten av serien fortsetter jeg å plassere skript i ~ / bin / katalogen fordi de er brukerskript og skal kunne drives av brukere. Og det virker som om vi ikke trenger å rote med $ PATH-variabelen for hånd for å få ting til å fungere.

    Gjenta kommandoer med løkker

    La oss komme til et av de mest nyttige verktøyene i geek arsenalen for å håndtere gjentatte oppgaver: sløyfer. I dag diskuterer vi "for" sløyfer.

    Den grunnleggende oversikten over en for-loop er som følger:

    for VARIABLE i LIST; gjøre
    Command1
    Command2
    ...
    commandn
    ferdig

    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 avgrensere - 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 å markere det som kjørbar og legge til hash bang hack), se vår bash scripting grunnleggende artikkel.

    I den oppgir du følgende kode:

    for jeg i item1 item2 item3 item4 item5 item6; gjøre
    ekko "$ i"
    ferdig

    Når du kjører skriptet, bør du bare få disse listepostene som utgang.

    Ganske enkelt, ikke sant? La oss se hva som skjer hvis vi forandrer ting litt. Endre skriptet ditt slik at det står dette:

    for jeg i *; gjøre
    ekko "$ i"
    ferdig

    Når du kjører dette skriptet i en mappe, bør du få en liste over filer som den inneholder som utgang.

    La oss nå endre ekkokommandoen til noe mer nyttig - si zip-kommandoen. Nemlig legger vi til filer i et arkiv. Og, la oss få noen argumenter i blandingen!

    for jeg i $ @; gjøre
    zip arkiv "$ i"
    ferdig

    Det er noe nytt! "$ @" Er en snarvei for "$ 1 $ 2 $ 3 ... $ n". Med andre ord er det en fullstendig liste over alle argumenter du angav. Nå, se hva som skjer når jeg kjører skriptet med flere inngangsfiler.

    Du kan se hvilke filer som er i mappen min. Jeg kjørte kommandoen med seks argumenter, og hver fil ble lagt til i et zip-arkiv med navnet "archive.zip". Lett, rett?

    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 at den er lastet opp!


    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!