LXF135:DrBrown3

Материал из Linuxformat.

Перейти к: навигация, поиск

Содержание

Ути­ли­ты ко­пи­ро­ва­ния

Сле­дуя древ­ней ман­тре Perl «есть бо­лее чем один спо­соб сде­лать это», мы от­кры­ли мно­же­ст­во вариантов ко­пи­ро­вания файла.

Мой урок это­го ме­ся­ца – под­лин­ное воз­вра­ще­ние к ис­то­кам и од­на из са­мых фун­да­мен­таль­ных тем, ко­то­рых я ка­сал­ся. Он по­свя­щен ко­пи­ро­ва­нию. Ути­лит для этой це­ли боль­ше, чем вы мо­же­те счесть нуж­ным, и мы рас­смот­рим пол­дю­жи­ны из них.

Нач­нем с на­ча­ла, с ко­ман­ды cp. В про­стей­шем слу­чае она вы­гля­дит так:

$ cp файл-ис­точ­ник файл-на­зна­че­ние

Ес­ли по­след­ний ар­гу­мент cp – имя су­ще­ст­вую­ще­го ка­та­ло­га, в не­го мож­но ско­пи­ро­вать не­сколь­ко фай­лов од­ной ко­ман­дой. Спи­сок фай­лов ге­не­ри­ру­ет­ся по шаб­ло­ну. На­при­мер, я хо­чу ско­пи­ро­вать кар­тин­ки Джо в фор­ма­те JPEG в свой ка­та­лог images:

$ cp ~/joe/images/*.jpg images

Для столь не­слож­ной ко­ман­ды у cp по­ра­зи­тель­но мно­го оп­ций. Я упо­мя­ну три.

Оп­ция -r (ре­кур­сив­но) ко­пи­ру­ет ка­та­ло­ги ре­кур­сив­но. Она по­зво­ля­ет ско­пи­ро­вать це­лое под­де­ре­во фай­ло­вой сис­те­мы. На­при­мер, в ито­ге ко­ман­ды

$ cp -r /boot .

в те­ку­щем ка­та­ло­ге ока­жет­ся пол­ная ко­пия де­ре­ва ка­та­ло­гов /boot.

Оп­ция -a (ар­хи­ви­ро­вать) со­хра­ня­ет а­три­бу­ты ис­ход­но­го фай­ла, на­сколь­ко это воз­мож­но. На­при­мер, ес­ли файл ко­пи­ру­ет­ся су­пер­поль­зо­ва­телем-root, бу­дут со­хра­не­ны ис­ход­ные пра­ва дос­ту­па и вре­мя из­ме­не­ния фай­ла. При ко­пи­ро­ва­нии фай­ла обыч­ным поль­зо­ва­те­лем вла­дель­цем фай­ла ста­нет этот поль­зо­ва­тель. Оп­ция -a под­ра­зу­ме­ва­ет -r.

Оп­ция -b (ре­зерв­ная ко­пия) ве­лит cp соз­дать ре­зерв­ную ко­пию при пе­ре­за­пи­си су­ще­ст­вую­ще­го фай­ла. К име­ни фай­ла ре­зерв­ной ко­пии до­ба­вит­ся ~.

Боль­шой брат cp

scp (за­щи­щен­ное ко­пи­ро­ва­ние) – стар­ший брат cp. Этой ко­ман­дой мож­но ко­пи­ро­вать обыч­ные фай­лы, как и cp, но ос­нов­ное ее на­зна­че­ние – ко­пи­ро­ва­ние фай­лов с уда­лен­ных ком­пь­ю­те­ров по за­щи­щен­но­му SSH-со­еди­не­нию. Вы­гля­дит она при­мер­но так:

$ scp *.jpg james@servera.example.com:images
james@servera.example.com’s password:
storm1.jpg	  	 100%	 198KB	 197.7KB/s	 00:00
sunset1.jpg	  	 100%	 135KB	 135.2KB/s	 00:00
teaching1.jpg	  	 100%	 190KB	 190.1KB/s	 00:00
thegirls.jpg		 100%	 57KB	 56.9KB/s	 00:00
UNIX_highlighter.jpg	 100%	 80KB	 80.1KB/s	 00:00

Здесь мои фай­лы JPEG ко­пи­ру­ют­ся в ка­та­лог images ком­пь­ю­те­ра servera.example.com. james – имя мо­ей учет­ной за­пи­си на сер­ве­ре; ес­ли его опус­тить, бу­дет взя­то имя поль­зо­ва­те­ля, под ко­то­рым я ра­бо­таю на кли­ен­те. Об­ра­ти­те вни­ма­ние на двое­то­чие – это клю­че­вой эле­мент кон­ст­рук­ции, он со­об­ща­ет ко­ман­де, что я ко­пи­рую фай­лы на уда­лен­ный ком­пь­ю­тер. Имя ка­та­ло­га images ин­тер­пре­ти­ру­ет­ся отно­си­тель­но до­маш­не­го ка­та­ло­га поль­зо­ва­те­ля james на сер­ве­ре. Точ­но так же мож­но за­гру­жать фай­лы с уда­лен­но­го ком­пь­ю­те­ра. Мож­но да­же де­лать «ко­пи­ро­ва­ние от третье­го ли­ца», ко­гда и ис­ход­ный, и ре­зуль­ти­рую­щий файл на­хо­дят­ся на уда­лен­ных ком­пь­ю­те­рах.

Что­бы это ра­бо­та­ло, на уда­лен­ных ком­пь­ю­те­рах дол­жен быть ус­та­нов­лен и за­пу­щен де­мон SSH, и на них у вас долж­ны быть учет­ные за­пи­си.

У scp есть оп­ция ре­кур­сив­но­го ко­пи­ро­ва­ния (-r) и оп­ция со­хра­не­ния ат­ри­бу­тов (-p). Есть так­же оп­ция -C, вклю­чаю­щая сжа­тие пе­ре­да­вае­мых дан­ных, хо­тя, по мо­ему опы­ту, в до­воль­но бы­ст­рой се­ти это ско­рее за­мед­лит, чем ус­ко­рит.

rsync

Изначально, rsync – ути­ли­та уда­лен­ной син­хро­ни­за­ции, хо­тя ею мож­но поль­зо­вать­ся и как (ци­ти­рую man-стра­ни­цу) «улуч­шен­ной ко­ман­дой ко­пи­ро­ва­ния для по­все­днев­но­го ис­поль­зо­ва­ния». Так что мы мо­жем про­сто ко­пи­ро­вать ею ло­каль­ные фай­лы:

rsync файл-источник файл-назначение

Но сла­вит­ся rsync как сред­ст­во уда­лен­ной син­хро­ни­за­ции. Ее ал­го­ритм дель­та-пе­ре­сыл­ки зна­чи­тель­но сни­жа­ет объ­ем пе­ре­сы­лае­мых по се­ти дан­ных, от­прав­ляя толь­ко раз­ли­чия ме­ж­ду исход­ны­ми фай­ла­ми и фай­ла­ми, су­ще­ст­вую­щи­ми на по­лу­ча­те­ле.

Это ве­ли­ко­леп­ное сред­ст­во ре­зерв­но­го ко­пи­ро­ва­ния и зер­ка­ли­ро­ва­ния. По су­ще­ст­ву, вы го­во­ри­те ей: «сде­лай эту фай­ло­вую сис­те­му здесь точ­но та­кой же, как та вон там», и она де­ла­ет это весь­ма эф­фек­тив­но. Син­так­сис этой ко­ман­ды очень по­хож на син­так­сис scp. Я мо­гу ско­пи­ро­вать весь мой ар­хив ста­тей Linux Format на уда­лен­ный сер­вер та­ким об­ра­зом:

$ rsync -av Linux-Format-Articles servera.example.com:
… тут бу­дет мно­го на­име­но­ва­ний …
sent 68556777 bytes received 14403 bytes 5079346.67 bytes/sec
total size is 68497001 speedup is 1.00

Ес­ли я со­хра­ню файл, ко­то­рый сей­час пи­шу (он на­зы­ва­ет­ся copying.txt) и по­вто­рю ко­ман­ду rsync, она за­вер­шит­ся поч­ти мгно­вен­но, так как пе­ре­да­ет толь­ко раз­ли­чия ме­ж­ду фай­ла­ми:

$ rsync -av Linux-Format-Articles servera.example.com:
sending incremental file list
sent 21426 bytes received 161 bytes 4797.11 bytes/sec
total size is 68497303 speedup is 3173.08

При ко­пи­ро­ва­нии на уда­лен­ные ком­пь­ю­те­ры rsync мо­жет ис­поль­зо­вать SSH или под­клю­чать­ся к де­мо­ну rsyncd.

rsync са­ма по се­бе – не сред­ст­во ре­зерв­но­го ко­пи­ро­ва­ния про­мыш­лен­но­го уров­ня, но ре­зерв­ное ко­пи­ро­ва­ние с по­мо­щью rsync на USB-бре­лок – пре­крас­ное ре­ше­ние для ин­ди­ви­ду­аль­ных поль­зо­ва­те­лей-про­фес­сио­на­лов.

wget

Пин­гви­нов столько, что всех и не пе­ре­ве­ша­ешь. А на­до ли ве­шать пин­гви­нов?

wget – не­ин­те­рак­тив­ная ути­ли­та ко­манд­ной стро­ки для ко­пи­ро­ва­ния фай­лов с URL-ад­ре­сов по про­то­ко­лам FTP, HTTP или HTTPS. Файл за­пи­сы­ва­ет­ся в те­ку­щий ка­та­лог. Вот при­мер:

$ wget http://archive.ubuntu.com/ubuntu/ls-lR.gz
--2010-06-14 13:43:57-- http://archive.ubuntu.com/ubuntu/ls-lR.gz
Resolving archive.ubuntu.com… 91.189.88.46, 91.189.88.30, ...
Connecting to archive.ubuntu.com… |91.189.88.46|:80…
connected.
HTTP request sent, awaiting response… 200 OK
Length: 9190681 (8.8M) [application/x-gzip]
Saving to: ‘ls-lR.gz’
100% [==================================>] 9,190,681
763K/s in 12 s
2010-06-14 13:48:05 (758 KB/s) – ‘ls-lR.gz’ saved
[9190681/9190681]

У wget то­же есть оп­ция ре­кур­сив­но­го ко­пи­ро­ва­ния (да, то­же -r), ко­то­рая ве­лит ей сле­до­вать ссыл­кам на HTML-стра­ни­цах, по су­ти вос­соз­да­вая ло­каль­ную ко­пию струк­ту­ры ка­та­ло­гов сай­та. При этом со­дер­жи­мое ко­пи­ру­ет­ся в ка­та­лог верх­не­го уров­ня с име­нем сай­та. На­при­мер, ко­ман­да

$ wget http://archive.ubuntu.com

ско­пи­ру­ет со­дер­жи­мое сай­та в ка­та­лог archive.ubuntu.com и бу­дет де­лать это очень дол­го!

На прак­ти­ке wget -r ра­бо­та­ет толь­ко для ста­ти­че­ских сай­тов, ко­то­рых сей­час все мень­ше и мень­ше. Тем не ме­нее, ути­ли­та очень удоб­на, ко­гда нуж­но за­гру­зить фай­лы с сай­та из скрип­та, или на сер­ве­ре без брау­зе­ра.

Из опи­сан­ных ути­лит лишь wget ра­бо­та­ет толь­ко в од­ном на­прав­ле­нии – с ее по­мо­щью мож­но ска­чать, но не за­ка­чать фай­лы. Од­на­ко для этой це­ли слу­жит ути­ли­та wput, ес­ли вам ин­те­рес­но.

При­чу­ды dd

Ко­ман­да dd – без­ус­лов­но, од­на из са­мых стран­ных бес­тий ми­ра Linux. У нее при­чуд­ли­вы и син­так­сис, и на­бор воз­мож­но­стей. С ее по­мо­щью мож­но про­сто ко­пи­ро­вать фай­лы:

$ dd if=/boot/vmlinuz-2.6.32-22-generic of=foo
7886+1 records in
7886+1 records out
4037792 bytes (4.0 MB) copied, 0.0290523 s, 139 MB/s

но это слег­ка ми­мо кас­сы. По­пут­но ути­ли­та мо­жет вы­пол­нять вся­че­ские не­мыс­ли­мые пре­об­ра­зо­ва­ния дан­ных: на­при­мер, пе­ре­вес­ти ниж­ний ре­гистр в верх­ний (и на­обо­рот) или пе­ре­де­лать ко­ди­ров­ку ASCII в EBCDIC (и на­обо­рот). (EBCDIC рас­шиф­ро­вы­ва­ет­ся как Extended Binary Coded Decimal Interchange Code – рас­ши­рен­ный дво­ич­но-де­ся­тич­ный код об­ме­на ин­фор­ма­ци­ей, эта ко­ди­ров­ка вве­де­на IBM и боль­ше ни­кем не ис­поль­зу­ет­ся). Она мо­жет по­ме­нять мес­та­ми че­ре­дую­щие­ся бай­ты и вы­ров­нять тек­сто­вые стро­ки по дли­не. Не­ко­то­рые из ее функ­ций яв­но на­це­ле­ны на ми­гра­цию дан­ных ме­ж­ду Unix/Linux и тра­ди­ци­он­ны­ми ком­пь­ю­те­ра­ми IBM. Но, по­жа­луй, са­мая по­лез­ная воз­мож­ность dd – кон­троль раз­ме­ра бло­ков, в ко­то­рых бу­дет счи­ты­вать­ся вход­ной файл и за­пи­сы­вать­ся вы­ход­ной, а так­же воз­мож­ность за­да­ния чис­ла ко­пи­руе­мых бло­ков. Это да­ет поч­ву для ин­те­рес­ных экс­пе­ри­мен­тов. На­при­мер, файл раз­ме­ром 1 МБ, пол­ный ну­лей, мож­но соз­дать так:

$ dd if=/dev/zero of=allzeros bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.00476925 s, 220 MB/s

Здесь мы за­пи­сы­ва­ем один блок раз­ме­ром 1 МБ. Стиль ука­за­ния фай­ла-ар­гу­мен­та if=/dev/zero со­вер­шен­но чужд Linux и не под­дер­жи­ва­ет спец­сим­во­лы (шаб­ло­ны). Об­ра­ти­те вни­ма­ние на же­ла­ние dd со­об­щать вам о том, ка­кой объ­ем дан­ных ско­пи­ро­ван и насколько бы­ст­ро это про­изош­ло. Ути­ли­та так­же спо­соб­на кло­ни­ро­вать диск. Здесь, на­при­мер, мы соз­да­ем об­раз раз­де­ла /dev/sda1 и за­пи­сы­ва­ем его в файл:

$ sudo dd if=/dev/sda1 of=sda1-image bs=64M
1+1 records in
1+1 records out
123346944 bytes (1.0 MB) copied, 0.00476925 s, 220 MB/s

Не­зва­ный гость

По­след­нее яв­ле­ние на ве­че­рин­ке ути­лит ко­пи­ро­ва­ния сма­хи­ва­ет на не­зва­но­го гос­тя: это ско­рее ути­ли­та ар­хи­ви­ро­ва­ния, чем ко­пи­ро­ва­ния. Зо­вут ее tar. Од­на­ко, на­прав­ляя дан­ные в tar и по­лу­чая их от­ту­да, мож­но ко­пи­ро­вать ие­рар­хии фай­лов. Трюк со­сто­ит в том, что­бы ука­зать ‘-‘ в ка­че­ст­ве име­ни вы­ход­но­го или вход­но­го фай­ла, что за­ста­вит tar пи­сать в стан­дарт­ный вы­вод или чи­тать со стан­дарт­но­го вво­да. Здесь я ко­пи­рую свой ка­та­лог ста­тей Linux Format в ка­та­лог /tmp:

$ tar cf - Linux-Format-Articles/ | (cd /tmp; tar xf -)

Точ­но так же мож­но соз­дать ка­нал че­рез SSH-со­еди­не­ние и ско­пи­ро­вать фай­лы на уда­лен­ные ком­пь­ю­те­ры:

$ tar cf - source-dir | ssh servera.example.com tar xf -

Дер­жу па­ри, что вы до это­го не до­ду­ма­лись!

Что в име­ни те­бе мо­ем?

dd бе­рет на­зва­ние из язы­ка управ­ле­ния за­да­ния­ми (JСL) мейн­фрей­мов IBM – это со­кра­ще­ние от “data definition” [оп­ре­де­ле­ние дан­ных]. От­ту­да же при­шел и стран­ный син­так­сис, столь не­удоб­ный в ко­манд­ной стро­ке Linux. Вы­гля­дел он при­мер­но так:

//QSAM0080 DD DSN=FOOBAR.DATA.QSAM0080,DISP=OLD,KEEP

Я ду­маю, что смог по­да­вить боль­шую часть сво­их вос­по­ми­на­ний о борь­бе с JСL в мои сту­ден­че­ские го­ды пер­фо­лент и пер­фо­карт. Мне обыч­но го­раз­до труд­нее да­ва­лись пол­дю­жи­ны строк на JСL, чем сле­дую­щие за ни­ми 200 строк на Fortran. Обыч­но я по­лу­чал рас­пе­чат­ку об ошиб­ке (уч­ти­те, вы­да­ча бы­ла раз в пол­дня), гла­сив­шую «от­сут­ст­ву­ет за­пя­тая в стро­ке 3». Мно­го раз я ди­вил­ся: по­че­му, зная, что там не хва­та­ет за­пя­той, ком­пь­ю­тер не мо­жет про­сто пред­ста­вить, что она там есть, и дви­нуть­ся даль­ше?

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию