
Ebben a cikkben néhány nem nyilvánvaló dolgot tárgyalunk a wildcards használatával kapcsolatban. a másolás során fellépő kétértelmű viselkedésekről, valamint olyan módszerekről, amelyek lehetővé teszik, hogy helyesen másoljunk be nagy mennyiségű fájlt, kihagyások és hibák nélkül. cp Tegyük fel, hogy mindent át szeretnénk másolni a /source könyvtárból a /target könyvtárba.
Elsőre az jut eszünkbe, hogy:
cp /source/* /target
Azonnal javítsuk ki ezt a parancsot:cp -a /source/* /target
ez hozzáadja az összes attribútum, jog másolását, és rekurszív másolást is végez. Amennyiben nem szükséges a jogok pontos másolása, elegendő a következő opció. Kulcs -a Másolás után észrevesszük, hogy nem minden fájl másolódott át — figyelmen kívül hagyták a ponttal kezdődő fájlokat, mint például: -r.
és hasonlókat.
.profil
.helyi
.mc
Miért történt ez?
Azért, mert a wildcards-t a shell kezel (
tipikus esetben). Alapértelmezetten a bash figyelmen kívül hagyja az összes fájlt, amely ponttal kezdődik, mivel ezeket rejtettnek tekinti. Az ilyen viselkedés elkerüléséhez módosítanunk kell a beállítást,bash a következő parancs segítségével: bash shopt -s dotglob
Annak érdekében, hogy ez a módosítás újraindítás után is megmaradjon, készíthetünk egy wildcard.sh fájlt ezzel a parancssal az alábbi könyvtárban: (lehet, hogy a disztribúciód más könyvtárban található). /etc/profile.d Ha a forráskönyvtárban nincsenek fájlok, akkor a shell nem tud semmit helyettesíteni a csillaggal, és a másolás hibával zárul. Az ilyen helyzetek ellen ott van a
failglob nullglob és . Hazajárul fel kell állítanunk, amely megakadályozza a parancs végrehajtását. nullglobnem megfelelő, mivel a wildcards nélküli, nem találatot adó sort üres (nulla hosszúságú) sztringgé alakítja, ami . Hazajárul fel kell állítanunk hibát fog okozni. cp Ha azonban a könyvtárban több ezer fájl található, érdemes teljesen lemondani a wildcards használatáról. Az a helyzet, hogy
a wildcards-t nagyon hosszú parancssorozatra bontja, mint például: bash cp -a /source/a /source/b /source/c …… /target
A parancssor hosszának korlátozása van, amelyről a következő paranccsal tájékozódhatunk:Megkapjuk a parancssor maximális hosszát byte-ban:
getconf ARG_MAXVagy:
2097152xargs --show-limits
Kapunk valami ilyesmit:…. Maximum length of command we could actually use: 2089314 ….
Tehát próbáljuk meg teljesen elkerülni a wildcards használatát.Egyszerűen írjuk be:
cp -a /source /target
És itt találkozunk a viselkedés kétértelműségével. Ha a /target könyvtár nem létezik, akkor megkapjuk, amit akartunk. cpHa azonban a target könyvtár létezik, a fájlok a /target/source könyvtárba lesznek másolva.
Ha azonban a célmappa létezik, akkor a fájlok a /target/source mappába lesznek másolva.
Nem mindig tudjuk előre törölni a /target mappát, mivel fontos fájlok lehetnek benne, és a célunk például az, hogy kiegészítsük a /target fájlokat a /source fájljaival.
Ha a forrás- és célmappák azonos nevűek lennének, például a /source-ból a /home/source-ba másolnánk, akkor a parancs a következő lenne:
cp -a /source /homeMásolás után a fájlok a /home/source mappában kiegészítve a /source fájljaival találhatók.
Íme egy logikai feladat: kiegészíthetjük a fájlokat a célmappában, ha a mappák azonos nevűek, de ha különböznek, akkor a forrásmappa belekerül a célmappába. Hogyan másolhatjuk a fájlokat a /source-ból a /target-ba cp használatával wildcardok nélkül?
Ezt a káros korlátozást egy nem nyilvánvaló megoldással kerülhetjük el:
cp -a /source/. /targetAkik jól ismerik a DOS-t és a Linuxot, már mindent megértettek: minden mappában található 2 láthatatlan mappa, a „.” és a „..”, amelyek a jelenlegi és a szülő mappákra mutató szimbolikus mappák.
- Másoláskor
cpellenőrzi a /target/ létezését és megpróbálja létrehozni azt. - Ilyen mappa létezik, és ez a /target
- A fájlok a /source-ból helyesen lettek átmásolva a /target-ba.
Tehát emeljük ki a memóriánkban vagy a falon:
cp -a /source/. /target
Ennek a parancsnak a működése egyértelmű. Minden hiba nélkül fog működni, függetlenül attól, hogy egymillió fájlunk van, vagy egyáltalán nincs.
Következtetések
Ha szükséges, hogy másoljuk mindent a fájlokat az egyik mappából a másikba, ne használjunk wildcardokat, helyettük jobban használjuk cp a forrásmappa végén egy pontot. Ez minden fájlt, beleértve a rejtett fájlokat is másolni fog, és nem fog összeomlani, ha egymillió fájl van, vagy teljesen hiányoznak a fájlok.
Utószó
ajánlott egy hasonló eredményű parancsot:
cp -a -T /source /target
cp -aT /source /target FIGYELEM: a betűk nagybetűségének jelentősége van. Ha összekevered, teljes zűrzavart kapsz: a másolás iránya meg fog változni. T A nagybetűs írásmód fontos. Ha elcseréli, akkor teljes káoszt kap: a másolás iránya megváltozik.
Köszönetnyilvánítás:
- A cégnek a támogatásért és a lehetőségért, hogy a blogomban publikálhassak a Habr-on.
- A képtől . A kép nagyon nagy és részletes, egy külön ablakban nyitható meg.
P.S. A megjegyzett hibákat kérlek privát üzenetben küldjétek el. Ezzel növelem a karmámat.
Forrás: habr.com
