ProHoster > Blog > uprava > cp naredba: ispravno kopiranje mapa datoteka u *nix
cp naredba: ispravno kopiranje mapa datoteka u *nix
Ovaj će članak otkriti neke neočite stvari vezane uz korištenje zamjenski znakovi kod kopiranja, dvosmisleno ponašanje naredbi cp prilikom kopiranja, kao i metode koje vam omogućuju ispravno kopiranje velikog broja datoteka bez preskakanja ili rušenja.
Recimo da trebamo kopirati sve iz mape /source u mapu /target.
Prvo što mi pada na pamet je:
cp /source/* /target
Odmah ispravimo ovu naredbu u:
cp -a /source/* /target
ključ -a će dodati kopiranje svih atributa, prava i dodati rekurziju. Kada nije potrebna točna reprodukcija prava, dovoljan je ključ -r.
Nakon kopiranja vidjet ćemo da nisu sve datoteke kopirane - datoteke koje počinju točkom poput:
.profile
.local
.mc
i slično.
Zašto se to dogodilo?
Budući da zamjenske znakove obrađuje ljuska (bash u tipičnom slučaju). Prema zadanim postavkama bash će zanemariti sve datoteke koje počinju točkama jer ih tretira kao skrivene. Kako bismo izbjegli ovakvo ponašanje, morat ćemo promijeniti ponašanje bash pomoću naredbe:
shopt -s dotglob
Kako biste osigurali da se ova promjena ponašanja nastavi nakon ponovnog pokretanja, možete stvoriti datoteku wildcard.sh ovom naredbom u mapi /etc/profile.d (Možda vaša distribucija ima drugu mapu).
A ako nema datoteka u izvornom direktoriju, tada ljuska neće moći ništa zamijeniti umjesto zvjezdice, a kopiranje također neće uspjeti s pogreškom. Postoje opcije protiv ove situacije failglob и nullglob. Trebat ćemo postaviti failglob, koji će spriječiti izvršenje naredbe. nullglob neće raditi, budući da pretvara niz sa zamjenskim znakovima koji nije pronašao podudaranje u prazan niz (nulte duljine), što za cp uzrokovat će pogrešku.
Međutim, ako u mapi postoje tisuće ili više datoteka, pristup zamjenskim znakovima treba u potpunosti napustiti. Činjenica je da bash proširuje zamjenske znakove u vrlo dugačku naredbenu liniju kao što je:
cp -a /souce/a /source/b /source/c …… /target
Postoji ograničenje duljine naredbenog retka koje možemo saznati pomoću naredbe:
getconf ARG_MAX
Uzmimo maksimalnu duljinu naredbenog retka u bajtovima:
2097152
ili:
xargs --show-limits
Dobivamo nešto poput:
….
Maximum length of command we could actually use: 2089314
….
Dakle, bez zamjenskih znakova.
Samo pišimo
cp -a /source /target
I tu se suočavamo s dvosmislenošću ponašanja cp. Ako mapa /target ne postoji, tada ćemo dobiti ono što nam treba.
Međutim, ako ciljna mapa postoji, datoteke će se kopirati u mapu /target/source.
Ne možemo uvijek izbrisati mapu /target unaprijed, budući da ona može sadržavati datoteke koje su nam potrebne, a naš je cilj, na primjer, dopuniti datoteke u /target datotekama iz /source.
Ako su izvorna i odredišna mapa nazvane isto, na primjer, kopirali smo iz /source u /home/source, tada bismo mogli upotrijebiti naredbu:
cp -a /source /home
A nakon kopiranja, datoteke u /home/source bile bi dopunjene datotekama iz /source.
Ovo je logičan problem: možemo dodati datoteke u odredišnu mapu ako su mape nazvane jednako, ali ako su različite, onda će izvorna mapa biti smještena unutar odredišne. Kako kopirati datoteke iz /source u /target koristeći cp bez zamjenskih znakova?
Da bismo zaobišli ovo štetno ograničenje, koristimo neočito rješenje:
cp -a /source/. /target
Oni koji poznaju DOS i Linux već su sve shvatili: unutar svake mape postoje 2 nevidljive mape “.” i “..”, koje su pseudo-mape poveznice na trenutne i više direktorije.
Prilikom kopiranja cp provjerava postojanje i pokušava stvoriti /target/.
Takav direktorij postoji i to je /target
Datoteke iz /source ispravno se kopiraju u /target.
Dakle, objesite ga u podebljani okvir za sjećanje ili na zid:
cp -a /source/. /target
Ponašanje ove naredbe je jasno. Sve će raditi bez grešaka, bez obzira imate li milijun datoteka ili nijednu.
Zaključci
Ako trebate kopirati sve datoteke iz jedne mape u drugu, ne koristimo zamjenske znakove, bolje ih je koristiti umjesto njih cp u kombinaciji s točkom na kraju izvorne mape. Ovo će kopirati sve datoteke, uključujući skrivene, i neće uspjeti s milijunima datoteka ili bez ikakvih datoteka.
pogovor
vmspike predložio verziju naredbe sa sličnim rezultatom: