
I den hÀr artikeln kommer vi att avslöja nÄgra obekanta saker relaterade till anvÀndning av 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/* /targetLÄ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 âŠâŠ /targetDet finns en begrĂ€nsning för lĂ€ngden pĂ„ kommandoraden, vilket vi kan ta reda pĂ„ genom att anvĂ€nda kommandot:
getconf ARG_MAXVi fÄr den maximala lÀngden pÄ kommandoraden i byte:
2097152Eller:
xargs --show-limitsVi 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 /homeOch 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/. /targetDe 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
cpkontrollerar 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
föreslog ett liknande command som ger samma resultat:
cp -a -T /source /target
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 för stöd och möjligheten att publicera pÄ sin blogg pÄ Habré.
- För bilden . 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.
KĂ€lla: habr.com
