cp kommando: kopiera filmappar korrekt till *nix

cp kommando: kopiera filmappar korrekt till *nix

Den här artikeln kommer att avslöja några icke-uppenbara saker relaterade till användningen av jokertecken vid kopiering, tvetydigt kommandobeteende cp vid kopiering, samt metoder som låter dig kopiera ett stort antal filer korrekt utan att hoppa över eller krascha.

Låt oss säga att vi måste kopiera allt från /source-mappen till /target-mappen.

Det första som kommer att tänka på är:

cp /source/* /target

Låt oss omedelbart korrigera detta kommando till:

cp -a /source/* /target

nyckel -a kommer att lägga till kopiering av alla attribut, rättigheter och lägga till rekursion. När exakt återgivning av rättigheter inte krävs räcker det med en nyckel -r.

Efter kopiering kommer vi att upptäcka att inte alla filer kopierades - filer som börjar med en punkt som:

.profile
.local
.mc

och liknande.

Varför hände det här?

Eftersom jokertecken bearbetas av skalet (bash i ett typiskt fall). Som standard ignorerar bash alla filer som börjar med prickar, eftersom det behandlar dem som dolda. För att undvika detta beteende måste vi ändra beteende bash med hjälp av kommandot:

shopt -s dotglob

För att säkerställa att denna beteendeförändring kvarstår efter en omstart kan du skapa en wildcard.sh-fil med det här kommandot i mappen /etc/profile.d (Kanske har din distribution en annan mapp).

Och om det inte finns några filer i källkatalogen, kommer skalet inte att kunna ersätta någonting i stället för asterisken, och kopieringen kommer också att misslyckas med ett fel. Det finns alternativ mot denna situation failglob и nullglob. Vi kommer att behöva ställa in failglob, vilket kommer att förhindra att kommandot körs. nullglob kommer inte att fungera, eftersom den konverterar en sträng med jokertecken som inte hittade en matchning till en tom sträng (noll längd), vilket för cp kommer att orsaka ett fel.

Men om det finns tusentals filer eller fler i mappen, bör metoden med jokertecken överges helt. Faktum är att bash expanderar jokertecken till en mycket lång kommandorad som:

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

Det finns en gräns för längden på kommandoraden, vilket vi kan ta reda på med kommandot:

getconf ARG_MAX

Låt oss få den maximala längden på kommandoraden i byte:

2097152

Или:

xargs --show-limits

Vi får något i stil med:

….
Maximum length of command we could actually use: 2089314
….

Så låt oss klara oss helt utan jokertecken.

Låt oss bara skriva

cp -a /source /target

Och här står vi inför oklarhet i beteendet cp. Om /target-mappen inte finns, kommer vi att få det vi behöver.

Men om målmappen finns, kommer filerna att kopieras till mappen /target/source.

Vi kan inte alltid ta bort mappen /target i förväg, eftersom den kan innehålla filer vi behöver och vårt mål till exempel är att komplettera filerna i /target med filer från /source.

Om käll- och målmapparna hade samma namn, till exempel kopierade vi från /source till /home/source, då kunde vi använda kommandot:

cp -a /source /home

Och efter kopiering skulle filerna i /home/source kompletteras med filer från /source.

Detta är ett logiskt problem: vi kan lägga till filer i målkatalogen om mapparna heter samma namn, men om de är olika, kommer källmappen att placeras i destinationen. Hur kopierar man filer från /source till /target med cp utan jokertecken?

För att komma runt denna skadliga begränsning använder vi en icke-uppenbar lösning:

cp -a /source/. /target

De som är bekanta med DOS och Linux har redan förstått allt: inuti varje mapp finns det 2 osynliga mappar "." och "..", som är pseudo-mappar länkar till nuvarande och högre kataloger.

  • Vid kopiering cp söker efter existens och försöker skapa /target/.
  • En sådan katalog finns och det är /target
  • Filer från /source kopieras till /target korrekt.

Så häng den i en fet ram i ditt minne eller på väggen:

cp -a /source/. /target

Beteendet för detta kommando är tydligt. Allt kommer att fungera utan fel, oavsett om du har en miljon filer eller inga alls.

Resultat

Om du behöver kopiera alla filer från en mapp till en annan, vi använder inte jokertecken, det är bättre att använda dem istället cp kombinerat med en punkt i slutet av källmappen. Detta kommer att kopiera alla filer, inklusive dolda, och kommer inte att misslyckas med miljontals filer eller inga filer alls.

efterordet

vmspike föreslog en kommandoversion med liknande resultat:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

OBS: brevväska T har betydelsen. Om du blandar ihop det kommer du att få fullständigt skräp: kopieringsriktningen kommer att ändras.
Tack:

  • företaget RUVDS.COM för stöd och möjlighet att publicera på din blogg på Habré.
  • Per bild Trippelkoncept. Bilden är mycket stor och detaljerad, kan öppnas i ett separat fönster.

PS Vänligen skicka eventuella fel du märker i ett privat meddelande. Jag ökar min karma för detta.

cp kommando: kopiera filmappar korrekt till *nix

Källa: will.com

Lägg en kommentar