
I denne artikel vil vi afdække nogle ikke-åbenlyse ting relateret til brugen af ved kopiering, tvetydig opførsel af kommandoen cp ved kopiering, samt metoder til korrekt at kopiere et stort antal filer uden at gå glip af eller få fejl.
Lad os antage, at vi skal kopiere alt fra mappen /source til mappen /target.
Det første, der falder ind, er:
cp /source/* /targetLad os straks rette denne kommando til:
cp -a /source/* /target Nøgle -a tilføjer kopiering af alle attributter, rettigheder og tilføjer rekursion. Når præcis reproduktion af rettighederne ikke er påkrævet, er nøglen -r.
Efter kopiering opdager vi, at ikke alle filer er blevet kopieret — filer, der begynder med punktum, såsom:
.profil
.lokal
.mc
og lignende.
Hvorfor skete dette?
Fordi wildcards behandles af shell (bash i typisk tilfælde). Standard bash ignorerer alle filer, der begynder med punktummer, da den betragter dem som skjulte. For at undgå denne opførsel skal vi ændre adfærden bash med kommandoen:
shopt -s dotglob For at bevare denne adfærdsændring efter genstart kan du lave en fil wildcard.sh med denne kommando i mappen /etc/profile.d (måske i din distribution en anden mappe).
Og hvis der ikke er filer i kilde-mappen, vil shell ikke kunne indsætte noget i stedet for stjernen, og kopieringen vil også mislykkes med en fejl. For at forhindre en sådan situation findes der indstillinger failglob og nullglob. Vi skal indstille failglob, som ikke lader kommandoen udføre. nullglob vil ikke fungere, da den konverterer strengen med wildcards, der ikke finder nogen match, til en tom streng (nul længde), hvilket vil forårsage en fejl for cp .
Men hvis der er tusindvis af filer i mappen, er det helt i orden at opgive tilgangen med wildcards. Det skyldes, at bash udvider wildcards til en meget lang kommandolinje, som ser sådan ud:
cp -a /source/a /source/b /source/c …… /targetDer er en grænse for længden af kommandolinjen, som vi kan finde ud af ved at bruge kommandoen:
getconf ARG_MAXVi får den maksimale længde af kommandolinjen i bytes:
2097152Eller:
xargs --show-limitsVi får noget af lignende:
….
Maximum length of command we could actually use: 2089314
….Så lad os helt undgå wildcards.
Lad os bare skrive
cp -a /source /target Og her støder vi på tvetydigheden i opførelsen. cpHvis mappen /target ikke findes, vil vi få det, vi har brug for.
Men hvis mappen target eksisterer, vil filerne blive kopieret til mappen /target/source.
Vi kan ikke altid fjerne mappen /target på forhånd, da der kan være nødvendige filer i den, og vores mål er for eksempel at supplere filerne i /target med filer fra /source.
Hvis mapperne kilde og modtager hedder det samme, for eksempel hvis vi kopierede fra /source til /home/source, kunne vi bruge kommandoen:
cp -a /source /homeOg efter kopieringen ville filerne i /home/source være suppleret med filer fra /source.
Her er en logisk opgave: vi kan supplere filerne i modtagerens katalog, hvis mapperne hedder det samme, men hvis de er forskellige, vil kilde-mappen blive placeret inde i modtageren. Hvordan kopierer man filer fra /source til /target med cp uden wildcards?
For at omgå denne skadelige begrænsning bruger vi en uklar løsning:
cp -a /source/. /targetDe, der er godt bekendt med DOS og Linux, forstår allerede det hele: inde i hver mappe er der 2 usynlige mapper “.” og “..”, som fungerer som pseudomapper-links til den nuværende og den overordnede katalog.
- Ved kopiering
cptjekker den for eksistens og forsøger at oprette /target/. - En sådan mappe eksisterer, og det er /target
- Filerne fra /source er blevet korrekt kopieret til /target.
Så lad os hænge det i en fed ramme i vores hukommelse eller på væggen:
cp -a /source/. /target
Adfærden af denne kommando er entydig. Det vil fungere uden fejl uanset om du har en million filer eller slet ingen.
Konklusioner
Hvis du skal kopiere alle filer fra én mappe til en anden, så brug ikke wildcards, i stedet er det bedre at bruge cp i kombination med punktummet i slutningen af kilde-mappen. Dette vil kopiere alle filer, inklusive skjulte og vil ikke fejle ved millioner af filer eller komplet fravær af filer.
Efterord
foreslog en tilsvarende kommando med samme resultat:
cp -a -T /source /target
cp -aT /source /target ADVARSEL: bogstavets T spil en rolle. Hvis du forveksler det, vil du få fuldstændig rod: retningen for kopieringen vil ændre sig.
Tak:
- Virksomheden for støtte og muligheden for at offentliggøre det i sin blog på Habr.
- For billedet . Billedet er meget stort og detaljeret, det kan åbnes i et separat vindue.
P.S. Send observerede fejl i private beskeder. J eg øger karmaen for det.
Kilde: habr.com
