See artikkel paljastab mõned ebaselged asjad, mis on seotud kasutamisega metamärgid kopeerimisel ebaselge käsukäitumine cp kopeerimisel, samuti meetodid, mis võimaldavad teil kopeerida tohutul hulgal faile ilma vahelejätmise või kokkujooksmiseta.
Oletame, et peame kopeerima kõik kaustast /source kausta /target.
Esimene asi, mis meelde tuleb, on:
cp /source/* /target
Parandame selle käsu kohe järgmiselt:
cp -a /source/* /target
võti -a lisab kõigi atribuutide, õiguste kopeerimise ja rekursiooni. Kui õiguste täpset reprodutseerimist ei nõuta, piisab võtmest -r.
Pärast kopeerimist leiame, et kõiki faile ei kopeeritud – punktiga algavad failid nagu:
.profile
.local
.mc
jms.
Miks see juhtus?
Kuna metamärke töötleb kest (bash tüüpilisel juhul). Vaikimisi ignoreerib bash kõiki faile, mis algavad punktidega, kuna käsitleb neid peidetuna. Sellise käitumise vältimiseks peame käitumist muutma bash kasutades käsku:
shopt -s dotglob
Selle käitumise muutuse püsimise tagamiseks pärast taaskäivitamist saate selle käsuga kaustas luua faili wildcard.sh /etc/profile.d (Võib-olla on teie levitusel teine kaust).
Ja kui lähtekataloogis pole faile, siis ei saa kest tärni asemel midagi asendada ja ka kopeerimine ebaõnnestub veaga. Selle olukorra vastu on võimalusi failglob и nullglob. Peame seadistama failglob, mis takistab käsu täitmist. nullglob ei tööta, kuna see teisendab metamärkidega stringi, mis ei leidnud vastet tühjaks stringiks (nullpikkus), mis cp põhjustab tõrke.
Kui aga kaustas on tuhandeid või rohkem faile, tuleks metamärkide lähenemisest üldse loobuda. Fakt on see, et bash laiendab metamärgid väga pikaks käsureaks, näiteks:
cp -a /souce/a /source/b /source/c …… /target
Käsurea pikkusel on piirang, mille saame teada käsuga:
getconf ARG_MAX
Vaatame käsurea maksimaalse pikkuse baitides:
2097152
Или:
xargs --show-limits
Saame midagi sellist:
….
Maximum length of command we could actually use: 2089314
….
Seega, teeme üldse ilma metamärkideta.
Lihtsalt kirjutame
cp -a /source /target
Ja siin seisame silmitsi käitumise mitmetähenduslikkusega cp. Kui kausta /target pole olemas, saame selle, mida vajame.
Kui aga sihtkaust on olemas, kopeeritakse failid kausta /target/source.
Me ei saa alati kausta /target eelnevalt kustutada, kuna see võib sisaldada meile vajalikke faile ja meie eesmärk on näiteks täiendada kaustas /target olevaid faile /source failidega.
Kui lähte- ja sihtkaustadel olid samad nimed, näiteks kopeerisime kaustast /source kausta /home/source, siis võiksime kasutada käsku:
cp -a /source /home
Ja pärast kopeerimist täiendatakse /home/source faile /source failidega.
See on loogiline probleem: me saame lisada faile sihtkataloogi, kui kaustadel on sama nimi, kuid kui need on erinevad, siis asetatakse lähtekaust sihtkoha sisse. Kuidas kopeerida faile asukohast /source asukohta /target, kasutades cp-d ilma metamärkideta?
Sellest kahjulikust piirangust mööda hiilimiseks kasutame mitteilmset lahendust.
cp -a /source/. /target
Need, kes tunnevad DOS-i ja Linuxit, on juba kõigest aru saanud: iga kausta sees on 2 nähtamatut kausta "." ja "..", mis on pseudokaustade lingid praegusesse ja kõrgematesse kataloogidesse.
Kopeerimisel cp kontrollib olemasolu ja proovib luua /target/.
Selline kataloog on olemas ja see on /target
Failid kaustast /source kopeeritakse õigesti kausta /target.
Niisiis, riputage see oma mällu või seinale paksu raami sisse:
cp -a /source/. /target
Selle käsu käitumine on selge. Kõik töötab vigadeta, olenemata sellest, kas teil on miljon faili või üldse mitte.
Järeldused
Kui teil on vaja kopeerida kõik failid ühest kaustast teise, me ei kasuta metamärke, parem on neid kasutada cp koos punktiga lähtekausta lõpus. See kopeerib kõik failid, sealhulgas peidetud failid, ja see ei ebaõnnestu miljonite failide või failide puudumise korral.
järelsõna
vmspike soovitas sarnase tulemusega käsuversiooni: