Tým cp: správné kopírování složek s soubory v *nix

Tým cp: správné kopírování složek s soubory v *nix

V tomto článku se odhalí některé skryté aspekty spojené s používáním wildcards při kopírování, nejednoznačné chování příkazu cp při kopírování a také způsoby, které umožňují správně kopírovat velké množství souborů bez přeskočení a selhání.

Představme si, že potřebujeme zkopírovat vše z adresáře /source do adresáře /target.

První, co nás napadne, je:

cp /source/* /target

Okamžitě opravíme tento příkaz na:

cp -a /source/* /target

Klíč -a což zahrne kopírování všech atributů, práv a přidá rekurzi. Když není potřeba přesná reprodukce práv, stačí klíč -r.

Po kopírování zjistíme, že nebyly zkopírovány všechny soubory — byly ignorovány soubory začínající tečkou, jako například:

.profil
.lokální
.mc

a podobně.

Proč se to stalo?

Protože wildcards zpracovává shell (bash v typickém případě). Ve výchozím nastavení bash ignoruje všechny soubory začínající tečkami, protože je považuje za skryté. Abychom se tomuto chování vyhnuli, budeme muset změnit chování bash pomocí příkazu:

shopt -s dotglob

Aby toto změněné chování přetrvalo po restartu, můžeme vytvořit soubor wildcard.sh s tímto příkazem v adresáři /etc/profile.d (možná ve vašem distribuci na jiném místě).

A pokud v adresáři source nejsou žádné soubory, shell nebude schopen nic dosadit místo hvězdičky a také kopírování selže. Proti takové situaci existují možnosti failglob a nullglob. Budeme potřebovat nastavit failglob, které nezpůsobí, že se příkaz provede. nullglob nevyhovuje, protože převede řetězec s wildcards, které nenašly shodu, na prázdný řetězec (nulové délky), což pro cp způsobí chybu.

Pokud však v adresáři existují tisíce souborů a více, je lepší bez wildcards úplně upustit. Ve skutečnosti bash rozbalí wildcards na velmi dlouhý příkazový řádek podobný:

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

Na délku příkazového řádku existuje omezení, které můžeme zjistit pomocí příkazu:

getconf ARG_MAX

Získáme maximální délku příkazového řádku v bajtech:

2097152

Nebo:

xargs --show-limits

Dostaneme něco jako:

….
Maximální délka příkazu, kterou můžeme skutečně použít: 2089314
….

Takže se zde budeme vyhýbat použití wildcards.

Jednoduše napišme

cp -a /source /target

A zde se setkáme s nejednoznačným chováním cp. Pokud adresář /target neexistuje, obdržíme to, co potřebujeme.

Pokud však adresář target existuje, soubory budou zkopírovány do adresáře /target/source.

Není vždy možné předem odstranit složku /target, protože v ní mohou být soubory, které potřebujeme, a naším cílem může být například doplnit soubory v /target soubory ze /source.

Pokud by se složky zdroje a příjemce jmenovaly stejně, například bychom kopírovali ze /source do /home/source, mohli bychom použít příkaz:

cp -a /source /home

A po zkopírování by soubory v /home/source byly doplněny soubory ze /source.

Tak zadání logické úlohy: můžeme doplnit soubory ve složce příjemce, pokud se názvy složek shodují, ale pokud se liší, pak bude složka zdroj umístěna uvnitř příjemce. Jak zkopírovat soubory ze /source do /target pomocí cp bez wildcards?

Abychom se vyhnuli tomuto nevhodnému omezení, použijeme neobvyklé řešení:

cp -a /source/. /target

Ti, kteří dobře znají DOS a Linux, už vše pochopili: uvnitř každé složky jsou 2 neviditelné složky „.“ a „..“, které jsou pseudo-složkami odkazujícími na aktuální a nadřazené adresáře.

  • Při kopírování cp ověřuje existenci a pokouší se vytvořit /target/.
  • Taková složka existuje a to je /target
  • Soubory ze /source byly správně zkopírovány do /target.

Takže to si zafixujme do paměti nebo na stěnu:

cp -a /source/. /target

Chování tohoto příkazu je jednoznačné. Vše proběhne bez chyb bez ohledu na to, zda máte milion souborů nebo žádné.

Závěry

Pokud potřebujete zkopírovat všechny soubory z jedné složky do druhé, nepoužívejte wildcards, raději použijte cp ve spojení s tečkou na konci složky zdroje. To zkopíruje všechny soubory, včetně skrytých, a nezkolabuje při milionech souborů nebo jejich úplné absenci.

Poznámka na závěr

vmspike navrhl podobnou variantu příkazu s podobným výsledkem:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

POZOR: velké písmeno T hraje roli. Pokud to zaměníte, dostanete naprostý chaos: směrem kopírování se změní.
Poděkování:

  • Společnosti RUVDS.COM za podporu a možnost publikovat ve svém blogu na Habru.
  • Za obrázek TripletConcept. Obrázek je velmi velký a detailní, lze ho otevřít v samostatném okně.

P.S. Zpozorované chyby hlaste do soukromé zprávy. Zvyšuju za to karmu.

Tým cp: správné kopírování složek s soubory v *nix

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster