
V tomto článku se odhalí některé skryté aspekty spojené s používáním 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/* /targetOkamž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 …… /targetNa délku příkazového řádku existuje omezení, které můžeme zjistit pomocí příkazu:
getconf ARG_MAXZískáme maximální délku příkazového řádku v bajtech:
2097152Nebo:
xargs --show-limitsDostaneme 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 /homeA 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/. /targetTi, 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í
cpověř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
navrhl podobnou variantu příkazu s podobným výsledkem:
cp -a -T /source /target
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 za podporu a možnost publikovat ve svém blogu na Habru.
- Za obrázek . 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.
Zdroj: habr.com
