cp-komento: kopioi tiedostokansiot oikein *nix-tiedostoon

cp-komento: kopioi tiedostokansiot oikein *nix-tiedostoon

Tämä artikkeli paljastaa joitain ei-ilmeisiä asioita, jotka liittyvät sovelluksen käyttöön jokerimerkit kopioitaessa epäselvää komentokäyttäytymistä cp kopioitaessa sekä menetelmiä, joiden avulla voit kopioida oikein valtavan määrän tiedostoja ohittamatta tai kaatumatta.

Oletetaan, että meidän on kopioitava kaikki /source-kansiosta /kohdekansioon.

Ensimmäisenä mieleen tuleva asia on:

cp /source/* /target

Korjataan tämä komento välittömästi seuraavasti:

cp -a /source/* /target

avain -a lisää kaikkien attribuuttien, oikeuksien kopioinnin ja lisää rekursion. Kun oikeuksien tarkkaa jäljentämistä ei vaadita, avain riittää -r.

Kopioinnin jälkeen huomaamme, että kaikkia tiedostoja ei kopioitu - tiedostot alkavat pisteellä, kuten:

.profile
.local
.mc

ja vastaavat.

Miksi näin kävi?

Koska komentotulkki käsittelee jokerimerkkejä (bash tyypillisessä tapauksessa). Oletuksena bash ohittaa kaikki pisteillä alkavat tiedostot, koska se käsittelee niitä piilotettuina. Välttääksemme tämän käytöksen meidän on muutettava käyttäytymistämme bash käyttämällä komentoa:

shopt -s dotglob

Voit varmistaa, että tämä käyttäytymismuutos jatkuu uudelleenkäynnistyksen jälkeen luomalla wildcard.sh-tiedoston tällä komennolla kansioon /etc/profile.d (Ehkä jakelussasi on eri kansio).

Ja jos lähdehakemistossa ei ole tiedostoja, kuori ei voi korvata mitään tähden sijasta, ja myös kopiointi epäonnistuu virheellä. Tätä tilannetta vastaan ​​on vaihtoehtoja failglob и nullglob. Meidän on asetettava failglob, joka estää komennon suorittamisen. nullglob ei toimi, koska se muuntaa jokerimerkkejä sisältävän merkkijonon, joka ei löytänyt vastaavuutta, tyhjäksi merkkijonoksi (pituus nolla), joka cp aiheuttaa virheen.

Jos kansiossa on kuitenkin tuhansia tiedostoja tai enemmän, jokerimerkkimenetelmästä tulisi luopua kokonaan. Tosiasia on, että bash laajentaa yleismerkit erittäin pitkäksi komentoriviksi, kuten:

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

Komentorivin pituudella on raja, jonka saamme selville komennolla:

getconf ARG_MAX

Otetaan komentorivin enimmäispituus tavuina:

2097152

Или:

xargs --show-limits

Saamme jotain tällaista:

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

Tehdään siis kokonaan ilman jokerimerkkejä.

kirjoitetaan vain

cp -a /source /target

Ja tässä kohtaamme käyttäytymisen epäselvyyden cp. Jos /target-kansiota ei ole, saamme tarvitsemamme.

Jos kohdekansio on kuitenkin olemassa, tiedostot kopioidaan /target/source-kansioon.

Emme voi aina poistaa /target-kansiota etukäteen, koska se voi sisältää tarvitsemiamme tiedostoja ja tavoitteemme on esimerkiksi täydentää /target-kansiossa olevia tiedostoja /source-tiedostoilla.

Jos lähde- ja kohdekansiot nimettiin samalla tavalla, esimerkiksi kopioimme hakemistosta /source kansioon /home/source, voisimme käyttää komentoa:

cp -a /source /home

Ja kopioinnin jälkeen /home/source-tiedoston tiedostoja täydennetään tiedostoilla /source.

Tämä on looginen ongelma: voimme lisätä tiedostoja kohdehakemistoon, jos kansioiden nimet ovat samat, mutta jos ne ovat erilaisia, lähdekansio sijoitetaan kohteen sisään. Kuinka kopioida tiedostoja /sourcesta /target-kohtaan käyttämällä cp:tä ilman jokerimerkkejä?

Tämän haitallisen rajoituksen kiertämiseksi käytämme ei-ilmeistä ratkaisua:

cp -a /source/. /target

Ne, jotka tuntevat DOS:n ja Linuxin, ovat jo ymmärtäneet kaiken: jokaisen kansion sisällä on 2 näkymätöntä kansiota "." ja "..", jotka ovat pseudokansiolinkkejä nykyiseen ja ylempään hakemistoon.

  • Kun kopioidaan cp tarkistaa olemassaolon ja yrittää luoda /target/.
  • Tällainen hakemisto on olemassa ja se on /target
  • Tiedostot hakemistosta /source kopioidaan oikein kansioon /target.

Joten ripusta se lihavoituun kehykseen muistiisi tai seinälle:

cp -a /source/. /target

Tämän komennon käyttäytyminen on selkeä. Kaikki toimii ilman virheitä riippumatta siitä, onko sinulla miljoona tiedostoa vai ei yhtään.

Tulokset

Jos haluat kopioida kaikki tiedostot kansiosta toiseen, emme käytä jokerimerkkejä, on parempi käyttää niitä sen sijaan cp yhdistettynä pisteeseen lähdekansion lopussa. Tämä kopioi kaikki tiedostot, myös piilotetut, eikä epäonnistu miljoonien tiedostojen kanssa tai ilman tiedostoja.

loppusanat

vmspike ehdotti komentoversiota samanlaisella tuloksella:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

HUOM: kirjekotelo T on merkitys. Jos sekoitat sen, saat täyttä roskaa: kopiointisuunta muuttuu.
Kiitos:

  • yhtiö RUVDS.COM tuesta ja mahdollisuudesta julkaista blogissasi Habressa.
  • per kuva Kolminkertainen konsepti. Kuva on erittäin suuri ja yksityiskohtainen, voidaan avata erilliseen ikkunaan.

PS. Ilmoita havaitsemasi virheet yksityisviestillä. Lisään karmaani tätä varten.

cp-komento: kopioi tiedostokansiot oikein *nix-tiedostoon

Lähde: will.com

Lisää kommentti