Hvorfor skal du bruke bash -skript for å utføre mappesynkroniseringer og sikkerhetskopiering?
Bash er den desidert mest populære og brukte SH-kompatible kommandospråklige tolken. I dag kan du finne bash nesten overalt, inkludert Microsoft Windows med det nye Windows -undersystemet for Linux. Stort sett all GNU/Linux -distribusjon leveres med bash som standardskall. Det samme gjelder macOS og noen andre UNIX-lignende operativsystemer.
Bash er ikke bare et kommandospråk; Som andre Unix -skjell, Bash er både et programmeringsspråk og en kommandotolk. Teknisk sett gir programmeringssiden av et skall brukere evner og funksjoner for å kombinere system- eller skallverktøy i en fil. Brukeren kan opprette kommandoer bare ved å kombinere kommandoer i en tekstfil; Disse spesielle typer tekstfil som inkluderer en samling kommandoer kalles skallskript, og når disse filene får tillatelse til å utføre, ser Shell -tolken dem som en enkelt kommando.
Fordelen med et bash-skript er at du kan bruke kommandolinjeverktøy direkte inne i det uten behov for import eller kilde eksterne biblioteker. Disse kommandolinjeverktøyene og innebygde verktøyene er kraftige og kan samhandle direkte med operativsystemet uten sammenstilling eller flere tolker; Vanligvis kjerneverktøy og kommandolinjegrensesnitt, som awk, xargs, finne, og grep, kan ha en mye bedre ytelse enn å bruke Python -skript og biblioteker for eksempel. Det er ikke vanskelig å finne folk som gjør avansert dataanalyse ved å bruke bare bashpt og GNU-innebygde verktøy. Andre hevder at denne typen tilnærminger kan være 235 x raskere enn en Hadoop -klynge - noe som ikke er så vanskelig å tro med tanke på noen klyngemonstrositeter du kan finne i dag bare for å passe til dårlige programvaredesign.
I denne saken oppstår ett spørsmål alltid: Hvis bash er så kraftig, hvorfor ikke bruke det til å automatisere alle de kjedelige tingene? Bash -syntaks er enkel og pragmatisk: det gir deg muligheten til å kombinere programmer for å automatisere vanlige oppgaver. Men når skriptet trenger å håndtere flere forhold eller samle for mange formål, er det på tide å vurdere et mer robust programmeringsspråk, som C eller andre skriptspråk, der Python og Perl er gode eksempler.
På den annen side er bash -skript veldig bra for enkeltoppgaver som intensjonen med denne artikkelen: å kombinere verktøy med muligheter for å se etter endringer i en bestemt mappe og deretter synkronisere filene. Et bashskript kan passe perfekt til denne oppgaven.
Hva trenger du for å utføre synkronisering eller autobackups?
Det er en stor liste over forskjellige metoder for å synkronisere mapper og filer. Antall applikasjoner som kan brukes til å utføre denne enkle oppgaven er stort, og noen av disse er tredjepartsløsninger. derimot, Denne artikkelen viser deg en mer elegant måte å oppnå det samme ved å bruke inotifywait og Rsync I et bash -manus. Generelt sett vil denne løsningen være lett, billig og, hvorfor ikke si, tryggere. I hovedsak er det bare inotify-tools, rsync og en stundsløyfe som er pålagt å fullføre dette oppdraget.
Hvordan du bruker inotifywait for autobacks og syncronizations?
inotifywait Bruker Inotify API for å vente på endringer i filer. Denne kommandoen var spesialdesignet for å brukes i skallskript. Et kraftig kjennetegn ved inotifywait er å se etter endringer kontinuerlig; Så snart nye hendelser oppstår, inotifywait skriver ut endringer og avkjørsler.
inotifywait Gir to alternativer som er veldig interessante for mappesynkronisering eller sikkerhetskopier i sanntid. Den første er den -r, -tilbakevendende alternativ; Som navnet tilsier, følger dette flagget ubegrensede underkatalogdybder i en spesifikk katalog som ble gitt som argumenter til inotifywait, unntatt symbolsk lenker.
De -e, -begivenhet Flag gir en annen interessant funksjon. Dette alternativet krever en liste over forhåndsdefinerte hendelser. Inotify-Tool-dokumentasjon viser mer enn 15 arrangementer for inotifywait; Men et enkelt sikkerhetskopierings- og synkroniseringssystem krever bare sletting, modifiser og opprette hendelser.
Følgende kommando er et godt eksempel på et virkelig verdensscenario:
$ inotifyWait -r -e Endre, opprette, slette/home/userdir/dokumenter
I dette tilfellet venter kommandoen på endringer - modifikasjoner, fil- eller mappekreasjoner eller eksklusjoner av noe slag - i fiktive /hjemme/brukerdir/dokumenter katalog. Så snart brukeren gjør noen endring, inotifywait gir ut modifiseringen og avkjørselen.
Antar at du oppretter en ny fil som heter Newfile inne i Dokumenter mappe mens inotifywait overvåker det. Når kommandoen oppdager filopprettelsen, sendes den ut
Dokumenter/ Opprett newfile
Med andre ord, inotifywait Skriver ut hvor modifiseringen skjer, hvilken type endringer den gjorde, og navnet på filen eller mappen som er endret.
Undersøkelse av utgangsstatus for inotifywait Når en endring finner sted, ser du en 0-exit-status som betyr en vellykket utførelse. Denne situasjonen er perfekt for et skallskript fordi en utgangsstatus kan brukes som en sann eller falsk tilstand.
Følgelig er det første trinnet i skriptet fullført: å finne et verktøy som venter på endringer i kataloger. Den andre er å søke etter et verktøy som kan synkronisere to kataloger, og Rsync er en perfekt kandidat.
Hvordan du bruker rsync for autobackups?
Rsync er en kraftig applikasjon. Du kan skrive en bok som beskriver alt du kan gjøre med dette allsidige verktøyet. Teknisk sett, Rsync er ikke noe mer enn et filkopieringsverktøy, en slags CP Kommando med steroider og spesielle krefter som sikre overføringsfiler. Bruken av Rsync I dette manuset er mer beskjeden, men ikke mindre elegant.
Hovedmålet er å finne en måte å:
De Rsync Dokumentasjon er godt skrevet; Kontrollere sammendraget av tilgjengelige alternativer, kan du enkelt velge -Avz flagg som det bedre valget. En enkel bruk ser ut som følger:
rsync -avz/
Det er viktig å legge en skråstrek etter opprinnelsesmappen. Tvert imot, Rsync kopierer hele opprinnelsesmappen (inkludert seg selv) til destinasjonsmappen.
For eksempel, hvis du oppretter to mapper, en som heter Originfolder og den andre målmappen, å lage Rsync Send til den andre hver endring som er gjort på den første, bruk den påfølgende kommandoen:
$ rsync -avz origenfolder/ destination mottker
Når du har opprettet en ny fil som heter Newfile, Rsync skriver ut noe sånt som:
Sende inkrementell filliste
./
Newfile
sendte 101 byte mottatt 38 byte 278.00 byte/sek
Total størrelse er 0 speedup er 0.00
I den første linjen skriver direktivet ut typen prosess, en inkrementell kopi; dette betyr at de Rsync Bruker komprimeringsfunksjonene for bare å øke filen og ikke endre hele arkivet. Siden det er første gang kommandoen blir utført, kopierer applikasjonen hele filen; Når nye endringer oppstår, er det bare trinn som finner sted. Den påfølgende utgangen er plasseringen, filnavnet og ytelsesdataene. Kontrollere utgangsstatusen til Rsync Kommando, du mottar en 0-exit for vellykket utførelse.
Så det er to viktige applikasjoner for å gi støtte i dette skriptet: Den ene er i stand til å vente på endringer, og den andre kan lage kopier av denne modifiseringen i sanntid. Her, det som mangler er en måte å koble begge verktøyene på en måte som Rsync tar grep så snart som inotifywait oppfatter enhver endring.
Hvorfor vi trenger en stundsløyfe?
Den enkleste løsningen for problemet over er en stundsløyfe. Med andre ord, ved hver anledning inotifywait eksisterer vellykket, bashskriptet må ringe Rsync å utføre sin økning; Umiddelbart etter at kopien skjer, må skallet gå tilbake til starttilstanden og vente på en ny avkjørsel av inotifywait kommando. Det er akkurat det en stundsløyfe gjør.
Du trenger ikke en omfattende bakgrunn innen programmering for å skrive et bash -manus. Det er veldig vanlig å finne gode systemadministratorer som ikke har noen eller veldig begrenset erfaring med programmering. derimot, Å lage funksjonelle skript er alltid en viktig oppgave med systemadministrasjon. Den gode nyheten er at konseptet bak en stund sløyfe er lett å forstå.
Følgende diagram representerer en stundsløyfe:
Uendelig mens sløyfediagram.
EN representerer inotifywait Kommando diskutert ovenfor og B, Rsync. Hver gang EN eksisterer med en 0-exit-status, skallet tolker det som sant; dermed mens sløyfe tillater utførelse av B; så fort B Også med hell ut EN igjen og gjentar sløyfen.
I dette tilfellet evaluerer mens Loop alltid evaluerer sann for EN. Teknisk genererer det en uendelig sløyfe, hva som er bra for foreslåret av dette skriptet; inotifywait vil tilbakevendende utføres, noe som betyr at den alltid vil vente på nye modifikasjoner.
Mer formelt er syntaks for en bash mens Loop er:
samtidig som
gjøre
Ferdig
betyr listen over forhold (EN) som må være sant; Så mens Loop kan utføre , Står for kommandoblokken (B). Hvis pre-test-sløyfen EN er falsk, så mens sløyfen går ut uten å henrette B.
Slik er Rsync og inotifywait Kommandoer passer inne i mens du er sløyfen,
Mens inotifyWait -r -e endrer, oppretter, slett origenfolder
gjøre
rsync -avz origenfolder/ destination mottker
Ferdig
Kombinere alt
Nå er det på tide å kombinere alt omtalt ovenfor for å lage et skallskript. Den første tingen er å lage en tom fil og navngi den; som et eksempel, LIVEBACKUP.bash representerer et godt valg. Det er god praksis å plassere skallskript i bin -mappen under brukerens hjemmekatalog, a.k.en. $ Hjem/bin.
Etter det kan du redigere filen i tekstredigereren etter eget valg. Den første linjen i et bashskript er veldig viktig; Det er her skriptet definerer tolkdirektivet, for eksempel:
#! [alternativer]
Shebang er dette rare symbolet med et hasj og et utropstegn (#!). Når skallet laster skriptet for første gang, ser det ut for dette tegnet, siden det indikerer hvilken tolk som må brukes til å kjøre programmet. Shebang er ikke en kommentar, og den må plasseres øverst på manuset uten mellomrom ovenfor.
Du kan la den første linjen være tom og ikke definere tolk. På denne måten bruker skallet standardtolk for å laste og utføre skriptet, men det er ikke godkjent. Det mest bevilgede og sikre valget er å indikere tolkdirektivet som følger:
#!/usr/bin/bash
Med tolkdirektivet eksplisitt slik, ser skallet etter bash -tolken under /usr /bin -katalogen. Ettersom oppgaven med dette skriptet er enkelt, er det ikke nødvendig å spesifisere flere kommandoer eller alternativer. En mer sofistikert mulighet er å ringe tolken ved å bruke Env -kommandoen.
#!/usr/bin/env bash
I denne sammenhengen søker skallet etter standard bas -kommandoen under det nåværende miljøet. Slik ordning er nyttig når brukermiljøet har viktige tilpasninger. Imidlertid kan det føre til sikkerhetsfeil på et bedriftsnivå når skallet ikke er i stand til å oppdage om kommandoen bash under et tilpasset miljø er eller ikke er en sikker tolk.
Når du setter alt sammen på dette tidspunktet, ser manuset ut:
#!/usr/bin/bash
Mens inotifyWait -r -e endrer, oppretter, slett opprinnelsesfolder
gjøre
rsync -avz origenfolder/ destination mottker
Ferdig
Hvordan bruke argumenter i et bash -skript?
Det som skiller dette skriptet fra en total funksjonalitet er hvordan det definerer opprinnelsen og destinasjonsmappen. For eksempel er det nødvendig å finne en måte å vise hva som er disse mappene. Den raskere modusen for å løse det spørsmålet er å bruke argumenter og variabler.
Her er et eksempel på riktig måte å referere til manuset på:
$ ./LIVEBACKUP.BASH/HOME/BRUKER/Origin/Hjem/Bruker/Destinasjon
Skallet laster noen av disse argumentene som er skrevet etter skriptnavnet og gir dem til skriptlasteren som variabler. For eksempel katalogen /Hjem/bruker/opprinnelse er det første argumentet, og du kan få tilgang til det i skriptet ved hjelp av $ 1. Dermed, $ 2 har en verdi av /Hjem/bruker/destinasjon. Alle disse posisjonsvariablene kan nås ved hjelp av dollarskiltet ($) etterfulgt av et n-nummer ($ n), hvor n er stillingen til argumentet der manuset kalles.
Dollarskiltet ($) har en veldig spesiell betydning og implikasjoner i skallskript; I andre artikler vil det bli diskutert i dybden. Foreløpig er puslespillet nesten løst.
#!/usr/bin/bash
Mens inotifyWait -r -e endrer, oppretter, slett $ 1
gjøre
rsync -avz $ 1/ $ 2
Ferdig
Merk: å håndtere for mange argumenter som bare bruker posisjonsparametere ($ n) kan raskt føre til dårlige design og forvirring i skallskript. En mer elegant måte å løse det problemet på er å bruke getopts kommando. Denne kommandoen hjelper deg også med å lage varsler om misbruk, hva kan være nyttig når andre brukere har tilgang til skriptet. Et raskt søk på internett kan vise forskjellige metoder for bruk getopts, Hva kan forbedre det nåværende skriptet hvis du trenger å gi flere bruksalternativer til andre brukere.
Gjør det kjøres
Bare en ting til må gjøres nå: for å lage filen LIVEBACKUP.bash kjørbar. Det kan enkelt utføres med Chmod kommando.
Gå til mappen som inneholder skriptet og typen:
$ chMod +x LIVEBACKUP.bash
Skriv deretter Dot-Slash-tegnet (./) Før skriptnavnet. DOT betyr i denne sammenhengen den gjeldende katalogen og skråstreken definerer en relativ vei til filen i den gjeldende katalogen. Med dette i bakhodet, må du også skrive inn opprinnelsesmappen som det første argumentet, etterfulgt av destinasjonsmappen som det andre, for eksempel:
$ ./LIVEBACKUP.BASH/HOME/BRUKER/Origin/Hjem/Bruker/Destinasjon
Alternativt kan du ringe skriptene ved å plassere mappens plassering i miljøveien eller kalle det et underskall, som:
$ Bash LIVEBACKUP.BASH/HOME/BRUKER/Origin/Hjem/Bruker/Destinasjon
Det første alternativet er et sikkert valg skjønt.
Eksempel på det virkelige liv
I et virkelig verdensscenario, manuelt kjører et sikkerhetskopieringsskript hver gang du starter systemet, kan være kjedelig. Et godt valg er å bruke en Cronjob eller tidtakere/service enheter med Systemd. Hvis du har mange forskjellige mapper å sikkerhetskopiere, kan du også opprette et annet skript som kilder LIVEBACKUP.bash; Dermed må kommandoen kalles bare en gang i en .service enhet. I en annen artikkel kan denne funksjonen diskuteres mer detaljert.
Hvis du bruker Windows -undersystemet for Linux, er det mulig å lage en grunnleggende oppgave for å kjøre skriptet ditt ved hjelp av "oppgavens planlegger" som utløses av systemstarten. Å bruke en batchfil for å ringe bash.EXE Med en liste over kommandoer er et godt valg. Du kan også bruke et Visual Basic -skript for å starte batchfilen i bakgrunnen.
Hvordan et pro bash -skript ser ut
Her er et eksempel på et manus designet av forfatteren som kan lese mer sofistikerte kommandolinjeargumenter.
#!/usr/bin/env bash
#
################################################################## plass ########################################################
################################################################## plass ########################################################
#
# Skript: SyncFolder.bash
# Forfatter: Diego Aurino da Silva
# Dato: 16. februar 2018
# Rev: 1.0
# Lisens: MIT (https: // github.com/Diegoaurino/bashscripts/blob/master/lisens)
#
# Platform: WSL eller GNU/Linux
#
# Formål: Lite manus for å synkronisere endringer fra venstre til høyre fra to mapper
# Under WSL eller GNU/Linux (krever inotify-tools)
#
################################################################## plass ########################################################
################################################################## plass ########################################################
#################
# GENERELLE INNSTILLINGER
#################
fet = $ (tput fet)
Normal = $ (TPUT SGR0)
origen = ""
destinasjon = ""
#################
# Alternativer -seksjon
#################
hvis [$# -EQ 0]
deretter
printf "\ n%s \ t \ t%s \ n \ n" "bruk $ fet -h $ normal for hjelp.""
Avslutt 1
ellers
mens getopts ": h" -alternativet
gjøre
sak $ alternativ i
h)
printf "\ n%s \ t \ t%s \ n \ n" "Bruk: ./SyncFolder.bash $ fet/origen/mappe $ normal -o $ fet/destinasjon/mappe $ normal "
Avslutt 0
;;
\? )
printf "\ n%s \ n \ n" "$ fet ugyldig alternativ for $ normal $ (basename $ 0)" 1> & 2
Avslutt 1
;;
Esac
Ferdig
skift $ ((Optind -1)))
Origen = $ 1
skifte
mens getopts ": o:" Alternativ
gjøre
sak $ alternativ i
o)
destinasjon = $ optarg
printf "\ n%s \ n \ n" "Følgende mapper blir synkronisert til venstre:"
printf "\ torigen: \ t \ t \ t%s \ n" "$ fet $ origen $ normal"
printf "\ tdestination: \ t \ t%s \ n \ n" "$ fet $ destinasjon $ normal"
;;
\? )
printf "\ n%s \ n \ n" "$ fet ugyldig alternativ for $ normal $ (basename $ 0): -$ optarg."1> & 2
Avslutt 1
;;
:
printf "\ n%s \ n \ n" "$ fet Alternativet $ normal -$ OptArg krever en katalog som argument."1> & 2
Avslutt 1
;;
*)
printf "\ n%s \ n \ n" "$ fet unkown -alternativet for $ normal $ (basename $ 0): -$ optarg."1> & 2
Avslutt 1
;;
Esac
Ferdig
skift $ ((Optind -1)))
fi
#################
# Synkroniserende seksjon
#################
Mens inotifyWait -r -e endrer, oppretter, slett $ origen
gjøre
rsync -avz $ origen/ $ destinasjon --delete --filter = 'P .git '
Ferdig
Utfordringer
Som en utfordring, prøv å designe ytterligere to versjoner av det nåværende skriptet. Den første trenger å skrive ut en loggfil som lagrer hver endring som finnes av inotifywait kommando og hver trinn utført av Rsync. Den andre utfordringen er å lage et synkroniseringssystem for to retninger ved å bruke bare en stund loop som forrige skript. Et råd: det er lettere enn det ser ut.
Du kan dele dine funn eller spørsmål på Twitter @linuxhint