cp-kommando: korrekt kopiering af mapper med filer i *nix

cp-kommando: korrekt kopiering af mapper med filer i *nix

Denne artikel vil afdække nogle uopdagede ting relateret til brugen af wildcards ved kopiering, tvetydig adfærd af kommandoen cp ved kopiering, samt måder som muliggør korrekt kopiering af et stort antal filer uden udeladelser og nedbrud.

Lad os sige, vi skal kopiere alt fra mappen /source til mappen /target.

Det første, der falder én ind, er:

cp /source/* /target

Lad os straks rette denne kommando til:

cp -a /source/* /target

Flag -a tilføjer kopiering af alle attributter, rettigheder og tilføjer rekursion. Når præcise reproduktioner af rettigheder ikke er nødvendige, er det nok med flaget -r.

Efter kopiering vil vi opdage, at ikke alle filer blev kopieret — filer, der begynder med punktum blev ignoreret, som:

.profil
.lokal
.mc

og lignende.

Hvorfor skete dette?

Fordi wildcards behandles af shell (bash i typiske tilfælde). Som standard ignorerer bash alle filer, der begynder med punktum, da de betragtes som skjulte. For at undgå denne adfærd skal vi ændre adfærden bash ved hjælp af kommandoen:

shopt -s dotglob

For at bevare denne adfærdsændring efter genstart kan du oprette en fil wildcard.sh med denne kommando i mappen /etc/profile.d (måske en anden mappe i din distribution).

Og hvis der ikke er nogen filer i kilde-mappen, kan shell ikke indsætte noget i stedet for stjernen, og kopieringen vil også afslutte med en fejl. For situationer som denne er der mulighederne failglob og nullglob. Vi har brug for at indstille failglob, som ikke vil tillade kommandoen at udføre. nullglob vil ikke være tilstrækkelig, da den konverterer den med wildcards, der ikke finder match, til en tom streng (null længde), hvilket for cp vil forårsage en fejl.

Men hvis der er tusindvis af filer i mappen, så er det bedst at helt undgå at bruge wildcards. Problemet er, at bash udvider wildcards til en meget lang kommandolinje, der ligner:

cp -a /souce/a /source/b /source/c …… /target

Der er en grænse for længden af kommandolinjen, som vi kan finde ud af ved at bruge kommandoen:

getconf ARG_MAX

Vi får maksimal længde af kommandolinjen i bytes:

2097152

Eller:

xargs --show-limits

Vi får noget i stil med:

….
Maksimal længde af den kommando, vi faktisk kunne bruge: 2089314
….

Så lad os helt undgå wildcards.

Lad os bare skrive

cp -a /source /target

Og her vil vi støde på tvetydigheden i adfærden cp. Hvis mappen /target ikke eksisterer, 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 slette mappen /target på forhånd, da den kan indeholde filer, vi har brug for, og vores mål er for eksempel at supplere filerne i /target med filerne fra /source.

Hvis mapperne for kilde og modtager havde det samme navn, for eksempel hvis vi kopierede fra /source til /home/source, kunne vi bruge kommandoen:

cp -a /source /home

Og efter kopieringen ville filerne i /home/source blive suppleret med filerne fra /source.

Sådan en logisk opgave: vi kan supplere filerne i modtagerdirektoriet, hvis mapperne hedder det samme, men hvis de er forskellige, vil kilde-mappen blive placeret inde i modtageren. Hvordan kan man kopiere filerne fra /source til /target ved hjælp af cp uden wildcard?

For at omgå denne skadelige begrænsning bruger vi en ikke-åbenlys løsning:

cp -a /source/. /target

De, som er godt bekendt med DOS og Linux, har allerede fanget det: inde i hver mappe er der to usynlige mapper "." og "..", som er pseudomapper-referencer til den nuværende og overliggende mapper.

  • Ved kopiering cp tjekker den eksisterende og forsøger at oprette /target/.
  • Sådan en mappe eksisterer, og det er /target
  • Filene fra /source er blevet kopieret til /target korrekt.

Så lad os hænge dette i en fed ramme i vores hukommelse eller på væggen:

cp -a /source/. /target

Adfærden i denne kommando er entydig. Alt vil fungere uden fejl uanset om du har millioner af filer eller slet ingen.

Konklusioner

Hvis du har brug for at kopiere alle filer fra en mappe til en anden, skal vi ikke bruge wildcard, i stedet er det bedre at bruge cp kombineret med punktet i slutningen af kilde-mappen. Dette vil kopiere alle filer, inklusive skjulte, og vil ikke fejle ved millioner af filer eller total mangel på filer.

Efterord

vmspike foreslog et svarende kommando-parameter:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

OPMÆRKSOMHED: bogstavets registrering T er vigtig. Hvis du forveksler det, får du en total rod: retningen af kopieringen vil ændre sig.
Tak:

  • Virksomheden RUVDS.COM for støtte og muligheden for at offentliggøre på sin blog på Habr.
  • For billedet TripletConcept. Billedet er meget stort og detaljeret, det kan åbnes i et separat vindue.

P.S. Send eventuelle fejl, du bemærker, i en direkte besked. Det forbedrer min karma.

cp-kommando: korrekt kopiering af mapper med filer i *nix

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster