Hjemmeside » hvordan » Nybegynderens Guide til Shell Scripting 2 Til Loops

    Nybegynderens Guide til Shell Scripting 2 Til Loops

    Hvis du ønsker at opbygge din geekkredit, skal du slutte os til den anden rate i vores shell scripting-serie. Vi har nogle rettelser, et par forbedringer i sidste uges script og en guide til looping for de uindviede.

    Datecp Script Revisited

    I den første del af vores shell scripting guide lavede vi et script, der kopierede en fil til en sikkerhedskatalog efter tilføjelse af datoen til slutningen af ​​filnavnet.

    Samuel Dionne-Riel påpegede i kommentarerne, at der er en meget bedre måde at håndtere vores variable referencer på.

    Argumenter er rumskilt i bash-skalen, det vil tilkendes, når der er plads i den resulterede udvidede kommando. I dit script, cp $ 1 $ 2. $ date_formatted vil fungere efter hensigten, så længe de udvidede variabler ikke har mellemrum i dem. Hvis du ringer dit script på denne måde: datecp "mit gamle navn" "mit nye navn" Udvidelsen vil resultere i denne kommando: cp mit nye navn mit gamle navn.the_date som faktisk har 6 argumenter.

    For at kunne rette op på dette problem skal den sidste linje i scriptet være: cp "$ 1" "$ 2. $ date_formatted"

    Som du kan se, ændrer vi vores scripts linje fra:

    cp -iv $ 1 $ 2. $ date_formatted

    til:

    cp -iv "$ 1" "$ 2". $ date_formatted

    vil tage sig af dette problem, når du bruger scriptet på filer, der har mellemrum i navnet. Samuel gør også det punkt, at når du kopierer og indsætter kode fra dette websted (eller internettet generelt), skal du sørge for at erstatte de korrekte bindestreger og citater til de "typografisk bedre", der ofte erstatter dem. Vi gør også mere for at sikre, at vores kode er mere kopi / indsæt venlig. ;-)

    En anden kommenterer, Myles Braithwaite, besluttede at udvide vores script, så datoen kunne ses før filtypen. Så i stedet for

    tastyfile.mp3.07_14_11-12.34.56

    vi ville få det her:

    tastyfile.07_14_11-12.34.56.mp3

    hvilket ender med at være lidt mere bekvemt for de fleste brugere. Hans kode er tilgængelig på hans GitHub side. Lad os tage et kig på, hvad han bruger til at trække fra 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 ændret formateringen lidt, men du kan se, at Myles erklærer hans datafunktion i Linje 1. I Linje 2 bruger han dog kommandoen "Echo" med det første argument i scriptet for at udlade filens navn. Han bruger pipekommandoen til at tage den output og bruge den som input til næste del. Efter røret kalder Myles kommandoen "awk", som er et kraftigt mønsterscanningsprogram. Ved at bruge -F-flag, fortæller han kommandoen, at det næste tegn (efter et mellemrum) er, hvad der vil definere "feltseparatoren". I dette tilfælde er det en periode.

    Nu, awk se en fil med navnet "tastyfile.mp3" som består af to felter: "tastyfile" og "mp3". Endelig bruger han

    'print $ NF'

    for at vise det sidste felt. Hvis din fil har flere perioder - derfor gør du awk se flere felter - det vil kun vise den sidste, som er filtypen.

    I linje 3 opretter han en ny variabel for filens navn og bruger kommandoen "basename" til at referere til alt i $ 1 undtagen filudvidelsen. Dette gøres ved at bruge basenavn og give det $ 1 som dets argument, og derefter tilføje et mellemrum og filtypen. Filforlængelsen tilføjes automatisk på grund af variablen, der refererer til linje 2. Hvad dette ville gøre, er at tage

    tastyfile.mp3

    og drej det ind

    tastyfile

    Så i den sidste linje, Myles sammensætter kommandoen, der vil output alt i orden. Bemærk, at der ikke er nogen henvisning til $ 2, et andet argument for scriptet. Dette bestemte script vil kopiere den nævnte fil til din nuværende mappe i stedet. Great job Samuel og Myles!

    Running Scripts og $ PATH

    Vi nævner også i vores Grundlæggende artikel, at scripts ikke må refereres som kommandoer som standard. Det vil sige, du skal pege på skriptets vej for at køre det:

    ./manuskript

    ~ / Bin / script

    Men ved at placere dine scripts i ~ / bin /, kan du bare skrive deres navne overalt for at få dem til at køre.

    Commenters brugte lidt tid på at diskutere, hvordan det var korrekt, da ingen moderne Linux distro opretter denne mappe som standard. Derudover tilføjer ingen heller det til $ PATH-variablen som standard, hvilket er det, der kræves for at scripts skal køre som kommandoer. Jeg var lidt forvirret, fordi efter at have tjekket min $ PATH-variabel, var kommentatorerne rigtige, men kaldte scripts arbejdede stadig for mig. Jeg fandt ud af hvorfor: Mange moderne Linux distros opretter en speciel fil i brugerens hjemmekatalog - .profile.

    Denne fil læses af bash (medmindre .bash_profile er til stede i brugerens hjemmekatalog) og i bunden er der et afsnit, der tilføjer ~ / bin / mappen til $ PATH-variablen, hvis den findes. Så er dette mysterium ryddet op. For resten af ​​serien fortsætter jeg med at placere scripts i ~ / bin / biblioteket, fordi de er brugerskrifter og skal kunne køres af brugere. Og det ser ud til, at vi ikke virkelig behøver at røre med $ PATH-variablen for hånd for at få tingene til at fungere.

    Gentag kommandoer med løkker

    Lad os komme til et af de mest nyttige værktøjer i geek arsenalen til at håndtere gentagne opgaver: sløjfer. I dag diskuterer vi "for" sløjfer.

    Den grundlæggende disposition for en for-loop er som følger:

    for VARIABLE i LIST; gøre
    Command1
    Command2
    ...
    commandn
    Færdig

    VARIABLE kan være en hvilken som helst variabel, men oftest er den små bogstaver "i" brugt ved konventionen. LIST er en liste over emner; Du kan angive flere elementer (adskille dem med et mellemrum), pege på en ekstern tekstfil eller bruge en asterisk (*) til at angive en fil i den aktuelle mappe. De angivne kommandoer er indrammet efter konventionen, så det er nemmere at se nesting - sætte sløjfer i sløjfer (så du kan sløjfe mens du sløjfer).

    Fordi lister bruger mellemrum som afgrænsere - det vil sige et mellemrum betegner et træk til det næste emne i listen - filer der har mellemrum i navnet er ikke særlig venlige. Lad os nu holde os til at arbejde med filer uden mellemrum. Lad os starte med et simpelt script for at vise navne på filer i den aktuelle mappe. Opret et nyt script i din ~ / bin / folder med titlen "loopscript". Hvis du ikke kan huske, hvordan du gør dette (herunder markering af det som eksekverbart og tilføjning af hash bang hack) henvises til vores bash scripting basics artikel.

    Indtast den følgende kode i den:

    for jeg i item1 item2 item3 item4 item5 item6; gøre
    ekko "$ i"
    Færdig

    Når du kører scriptet, skal du bare få disse listeposter som output.

    Ret simpelt, ikke? Lad os se, hvad der sker, hvis vi ændrer tingene lidt op. Skift dit script, så det siger dette:

    for jeg i *; gøre
    ekko "$ i"
    Færdig

    Når du kører dette script i en mappe, skal du få en liste over filer, som den indeholder som output.

    Lad os nu ændre ekkokommandoen til noget mere nyttigt - siger zip-kommandoen. Vi vil nemlig tilføje filer til et arkiv. Og lad os få nogle argumenter i blandingen!

    for jeg i $ @; gøre
    zip arkiv "$ i"
    Færdig

    Der er noget nyt! "$ @" Er en genvej til "$ 1 $ 2 $ 3 ... $ n". Det er med andre ord den fulde liste over alle de argumenter, du har angivet. Nu se hvad der sker, når jeg kører scriptet med flere inputfiler.

    Du kan se, hvilke filer der er i min mappe. Jeg sprang kommandoen med seks argumenter, og hver fil blev tilføjet til et zip-arkiv med navnet "archive.zip". Let, rigtigt?

    For sløjfer er temmelig vidunderlige. Nu kan du udføre batchfunktioner på lister over filer. Du kan f.eks. Kopiere alle scriptets argumenter til et zip-arkiv, flytte originalerne til en anden mappe og sikre automatisk kopi den zip-fil til en fjerncomputer. Hvis du opsætter nøglefiler med SSH, behøver du ikke engang at indtaste dit kodeord, og du kan endda fortælle scriptet om at slette zip-filen efter at have uploadet den!


    Brug af for-loops gør det nemt at lave en masse handlinger for alle filer i en mappe. Du kan stakke mange forskellige kommandoer sammen og bruge argumenter meget let til at oprette og flyve liste, og det er kun toppen af ​​isbjerget.

    Bash scripters, har du nogle forslag? Har du lavet et nyttigt script, der bruger sløjfer? Vil du dele dine tanker om serien? Forlad nogle kommentarer og hjælp andre scripting nybegyndere ud!