Team cp: korrekt kopiering av mappar med filer i *nix

Team cp: korrekt kopiering av mappar med filer i *nix

I den hÀr artikeln kommer vi att avslöja nÄgra obekanta saker relaterade till anvÀndning av wildcards vid kopiering, och otydligt beteende hos kommandot cp vid kopiering, samt sÀtt att korrekt kopiera stora mÀngder filer utan förluster eller kraschar.

Anta att vi behöver kopiera allt frÄn mappen /source till mappen /target.

Det första som kommer att tÀnka pÄ Àr:

cp /source/* /target

LÄt oss genast korrigera detta kommando till:

cp -a /source/* /target

Nyckeln -a lÀgger till kopiering av alla attribut, rÀttigheter och gör det rekursivt. NÀr exakt reproduktion av rÀttigheter inte krÀvs rÀcker nyckeln -r.

Efter kopieringen kommer vi att upptĂ€cka att inte alla filer kopierades — filer som börjar med en punkt, sĂ„som:

.profil
.lokal
.mc

och liknande.

Varför hÀnde detta?

För att wildcards hanteras av skalet (bash i typiska fall). Som standard ignorerar bash alla filer som börjar med punkter, eftersom de tolkas som dolda. För att undvika detta beteende mÄste vi Àndra beteendet bash med kommandot:

shopt -s dotglob

För att denna beteendeförÀndring ska bevaras efter omstart, kan vi skapa en fil wildcard.sh med detta kommando i mappen /etc/profile.d (det kan vara en annan mapp i din distribution).

Om det inte finns nÄgra filer i kÀllkatalogen kan skalet inte ersÀtta stjÀrnan och kopieringen kommer ocksÄ att sluta med ett fel. Det finns alternativ mot en sÄdan situation failglob och nullglob. Vi behöver stÀlla in failglob, vilket kommer att förhindra kommandot frÄn att köras. nullglob inte fungerar, eftersom det omvandlar raden med wildcards som inte matchat till en tom rad (noll lÀngd), vilket för cp kommer att orsaka ett fel.

Men om det finns tusentals filer i mappen bör vi helt överge tillvÀgagÄngssÀttet med wildcards. Anledningen Àr att bash expanderar wildcards till en mycket lÄng kommandorad liknande:

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

 /target

Det finns en begrÀnsning för lÀngden pÄ kommandoraden, vilket vi kan ta reda pÄ genom att anvÀnda kommandot:

getconf ARG_MAX

Vi fÄr den maximala lÀngden pÄ kommandoraden i byte:

2097152

Eller:

xargs --show-limits

Vi fÄr nÄgot som detta:


.
Maximum length of command we could actually use: 2089314

.

SÄ lÄt oss klara oss utan wildcards helt.

LÄt oss helt enkelt skriva

cp -a /source /target

Och hÀr kommer vi att stöta pÄ otydligheten i beteendet cp. Om mappen /target inte finns kommer vi att fÄ vad vi behöver.

Om mappen target redan finns, kommer filerna att kopieras till mappen /target/source.

Vi kan inte alltid ta bort mappen /target i förvÀg, eftersom det kan finnas filer dÀr som vi behöver, och vÄrt mÄl Àr att till exempel komplettera filerna i /target med filer frÄn /source.

Om kÀll- och mÄlmapparna hade samma namn, till exempel om vi kopierade frÄn /source till /home/source, skulle vi kunna anvÀnda kommandot:

cp -a /source /home

Och efter kopieringen skulle filerna i /home/source vara kompletterade med filer frÄn /source.

HÀr Àr en logisk uppgift: Vi kan komplettera filer i mÄl-mappen om mapparna har samma namn, men om de skiljer sig Ät kommer kÀll-mappen att placeras inuti mÄlen. Hur kopierar man filer frÄn /source till /target med cp utan wildcards?

För att kringgÄ denna skadliga begrÀnsning anvÀnder vi en ovÀntad lösning:

cp -a /source/. /target

De som Àr vÀl bekanta med DOS och Linux har redan förstÄtt: Inuti varje mapp finns tvÄ osynliga mappar «.» och «..», som Àr pseudomapper-lÀnkar till den aktuella och överordnade katalogen.

  • Vid kopiering cp kontrollerar den existensen och försöker skapa /target/.
  • Denna katalog finns och det Ă€r /target
  • Filer frĂ„n /source har kopierats korrekt till /target.

SÄ, lÄt oss hÀnga upp det i en fet ram i vÄr minne eller pÄ vÀggen:

cp -a /source/. /target

Kommandoets beteende Àr entydigt. Allt kommer att fungera utan fel oavsett om du har en miljon filer eller inte har nÄgra alls.

Slutsatser

Om du behöver kopiera alla filer frÄn en mapp till en annan, anvÀnd inte wildcards, istÀllet Àr det bÀttre att anvÀnda cp i kombination med punkten i slutet av kÀllmappen. Detta kommer att kopiera alla filer, inklusive dolda, och misslyckas inte vid miljontals filer eller fullstÀndig brist pÄ filer.

Epilog

vmspike föreslog ett liknande command som ger samma resultat:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

OBS: storleken pÄ bokstaven T Àr viktigt. Om du blandar ihop dem kommer du fÄ en fullstÀndig röra: riktningen för kopieringen kommer att förÀndras.
Tack:

  • Företaget RUVDS.COM för stöd och möjligheten att publicera pĂ„ sin blogg pĂ„ HabrĂ©.
  • För bilden TripletConcept. Bilden Ă€r vĂ€ldigt stor och detaljerad, kan öppnas i ett separat fönster.

P.S. Rapportera eventuella upptÀckta fel till mig. Jag ökar din karma för det.

Team cp: korrekt kopiering av mappar med filer i *nix

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster