Навигация по файловой системе
Следующее, что необходимо пользователю после создания файлов - ориентация среди существующего их изобилия. Для начала при этом неплохо определиться со своим текущим положением в файловой системе. Для этого предназначена команда pwd
. В ответ на нее выводится полный путь к текущему каталогу. Например, если текущим является домашний каталог пользователя, в ответ на:
$ pwd
последует
/home/username
Команда pwd
имеет всего две опции: -L
и -P
. Первая выводит т.н. логический путь к текущему каталогу. То есть, таковым является, скажем, каталог /usr/src/linux
, являющий собой символическую ссылку на каталог /usr/src/linux-номер_версии
, то в ответ на
$ pwd -L
так и будет выведено
/usr/src/linux
Впрочем, тот же ответ последует и на команду pwd
без опций вообще. Если же дать эту команду в форме
$ pwd -P
то будет выведен путь к физическому каталогу, на который ссылается текущий, например:
/usr/src/linux-2.4.19-gentoo-r9
Далее, по каталогам неплохо как-то перемещаться. Что делается командой cd
. В отличие от прочих команд, рассматриваемых в этом разделе, это - внутренняя команда, встроенная во все командные оболочки - бесполезно было бы искать соответствующий ей исполняемый файл. Однако это не уменьшает ее важности. Использование ее очень просто -
$ cd pathname
где pathname
- путь к искомому каталогу в абсолютной (относительно корня) или относительной (относительно текущего каталога) форме.
Определить местоположение команды (и вообще исполняемых файлов) в структуре файловой системы можно с помощью команды which
(это также встроенная команда оболочки). В качестве аргумента ее можно указать одно или несколько имен файлов, в ответ на что будет выведен полный путь к каждому из них:
$ which tcsh zsh bash
/bin/tcsh
/bin/zsh
/bin/bash
При наличии одноименных исполняемых файлов в разных каталогах по умолчанию будет выведен путь только к первому из них: для вывода всех файлов-"тезок" можно прибегнуть к опции -a
. При этом не важно, будут это жесткие или символические ссылки.
Более широкие возможности поиска - у команды whereis
. По умолчанию, без опций, она для заданного в качестве аргумента имени выводит список бинарных файлов, man-страниц и каталогов с исходными текстами:
$ whereis zsh
zsh: /bin/zsh /etc/zsh /usr/lib/zsh /usr/share/zsh
/usr/man/man1/zsh.1.gz /usr/share/man/man1/zsh.1.gz
Соответствующими опциями можно задать поиск файлов одного из этих типов: -b
- бинарных, -m
- страниц руководств, -s
- каталогов с исходниками. Дополнительные опции -B
, -M
, -S
(в сочетании с опцией -f
) позволяют определить исходные каталоги для их поиска.
Наконец, команда locate
осуществляет поиск всех файлов и каталогов, содержащих компонент имени, указанный в качестве аргумента и осуществляет вывод содержимого найденных каталогов. Так, в ответ на команду
$ locate zsh
будет выведен список вроде следующего:
/bin/zsh
/bin/zsh-4.0.6
/etc/zsh
/etc/zsh/zlogin
/etc/zsh/zshenv
/etc/zsh/zshrc
и так далее. Команда locate
при этом обращается к базе данных, расположенной в каталоге /var/spool/locate/locatedb
(точный путь в разных системах может варьировать). По умолчанию эта база данных пуста - и перед использованием команды locate
должна быть наполнена содержанием. Для этого предназначен сценарий /usr/bin//updatedb
, извлекающий сведения из базы данных установленных пакетов - /var/db/pkg
. При активной доустановке программ база эта нуждается в периодическом обновлении.
Приведенные команды относятся к поиску исполняемых файлов и программных компонентов. Однако чаще перед пользователем возникает необходимость поиска неких произвольных файлов. На сей предмет существует команда find
. Однако возможности ее не сводятся к поиску - это практически универсальный инструмент для файловых операций. И потому она будет подробно рассмотрена отдельно - в следующей заметке.
Наиболее универсальным средством получения практически исчерпывающей информации о файлах является команда ls
. Общая форма ее запуска -
$ ls [options] names
где в качестве аргумента names
могут выступать имена файлов или каталогов в любом количестве. Команда эта имеет многочисленные опции, основные из которых мы и рассмотрим.
Начать с того, что команда .
) и родительский (..
) каталог.
Для вывода всех без исключения имен файлов (в том числе и скрытых) предназначена опция -a
. Смысл опции -A близок - она выводит список имен всех файлов, за исключением имени текущего (.
) и родительского (..
) каталога.
Кроме имени, любой файл идентифицируется своим номером inode
. Для его вывода используется опция -i
:
$ ls -i
12144 content.html 12149 gentoo02.html
и так далее. Как и многие другие, команда ls
обладает способностью рекурсивной обработки аргументов, для чего предназначена опция -R
, выводящая список имен файлов не только текущего каталога, но и всех вложенных подкаталогов:
$ ls -R
unixforall:
about/ apps/ diffimages/ distro/ signature.html sys/
anons/ content/ difftext/ gentoo/ statistics/ u4articles/
unixforall/about:
about_lol.html about_lol.txt index.html
unixforall/anons:
anons_dc.html
В выводе команды ls
по умолчанию имена файлов разных типов даются абсолютно одинаково. Для их визуального различия используется опция -F
, завершающая имена каталогов символом слэша, исполнимых файлов - символом звездочки, символических ссылок - "собакой"; имена регулярных файлов, не имеющих атрибута исполнения, никакого символа не включают:
$ ls -F
dir1/ dir2/ dir3@ file1 file2* file3@
Другое средство для визуального различия типов файлов - колоризация, для чего применяется опция -G
. Цвета шрифта, воспроизводящего имена, по умолчанию - синий для каталогов, лиловый (magenta) для символических ссылок, красный - исполнимых файлов, и так далее. Для файлов устройств, исполнимых файлов с атрибутом "суидности", каталогов, имеющих атрибут sticky
, дополнительно колоризуется и фон, на котором выводится шрифта, воспроизводящий их имена. Подробности можно посмотреть секции ENVIRONMENT
man-страницы для команды ls
. Впрочем, колоризация работает не при всех настройках терминалов (и не во всех командных оболочках).
По умолчанию команда ls
выводит список файлов в порядке ASCII-кода первого символа имени. Однако есть возможность его сортировки в обратном порядке (-r
), в порядке времени модификации (-t
) или времени доступа (-tu
). Кроме того, опция -f
отменяет какую-либо сортировку списка вообще.
Информацию об объеме файлов можно получить, используя опцию -s
, выводящую для имени каждого файла его размер в блоках, а также суммарные объем всех выведенных файлов:
$ ls -s ../book
total 822
656 book.html
4 content1.html
86 var_part2.html
24 command.html
38 part2.html
6 command.txt
8 shell_tmp.html
Добавление к опции -s
еще и опции -k
(то есть ls -sk
) выведет всю ту же информацию в килобайтах. Очевидно, что если размер блока файловой системы, как это подчас бывает, составляет 1024 байта, вывод ls
с этими опциями будет одинаков.
Как можно видеть из всех приведенных выше примеров, списки файлов по команде ls
выводится в многоколоночном виде (чему соответствует опция -C
, однако указывать ее нет необходимости - многоколоночный вид принят для краткого формата по умолчанию). Но можно задать и одноколоночное представление списка посредством опции -1
:
$ ls -1
dir1
dir2
dir3
file1
file2
file3
До сих пор речь шла о кратком формате команды ls
. Однако более информативным является т.н. длинный ее формат, вывод в котором достигается опцией -l
и автоматически влечет за собой одноколоночное представление списка:
$ ls -l
total 8
drwxr-xr-x 2 alv alv 512 8 май 18:04 dir1
drwxr-xr-x 3 alv alv 512 8 май 17:43 dir2
lrwxr-xr-x 1 alv alv 4 9 май 07:59 dir3 -> dir2
-rw-r--r-- 1 alv alv 14 8 май 10:39 file1
-rwxr-xr-x 1 alv alv 30 9 май 08:02 file2
lrwxr-xr-x 1 alv alv 2 8 май 10:57 file3 -> f1
Можно видеть, что по умолчанию в длинном формате выводятся:
- сведения о типе файла (
-
- регулярный файл,d
- каталог,l
- символическая ссылка,c
- файл символьного устройства,b
- файл блочного устройства) и атрибуты доступа для различных атрибутов принадлежности (о чем было сказано достаточно); - количество жестких ссылок на данный идентификатор inode;
- имя пользователя - владельца файла, и группы пользователей, которой файл принадлежит;
- размер файла в блоках;
- время модификации файла с точностью до месяца, дня, часа и минуты (в формате, принятом в данной
locale
); - имя файла и (для символических ссылок) имя файла-источника.
Однако это еще не все. Добавив к команде ls -l
еще и опцию -i
, можно дополнительно получить идентификатор inode каждого файла, опция -n
заменит имя владельца и группу на их численные идентификаторы (UID и GUID, соответственно), а опция -T
выведет в поле времени модификации еще и годы, и секунды:
$ ls -linT
total 8
694402 drwxr-xr-x 2 1000 1000 512 8 май 18:04:56 2002 dir1
694404 drwxr-xr-x 3 1000 1000 512 8 май 17:43:31 2002 dir2
673058 lrwxr-xr-x 1 1000 1000 4 9 май 07:59:08 2002 dir3 -> dir2
673099 -rw-r--r-- 1 1000 1000 14 8 май 10:39:38 2002 file1
673059 -rwxr-xr-x 1 1000 1000 30 9 май 08:02:23 2002 file2
673057 lrwxr-xr-x 1 1000 1000 2 8 май 10:57:07 2002 file3 -> f1
Разумеется, никто не запрещает использовать в длинном формате и опции визуализации (-F
и -G
), и опции сортировки (-r
, t
, tu
), и любые другие, за исключением опции -C
- указание ее ведет к принудительному выводу списка в многоколоночной форме, что естественным образом подавляет длинный формат представления.
Я столь подробно остановился на описании команды ls
потому, что это - основное средство визуализации файловых систем любого Unix, при умелом использовании ничуть не уступающее развитым файловым менеджерам (типа Midnight Commander или Konqueror) по своей выразительности и информативности. И отнюдь не требующее для достижения таковых вбивания руками многочисленных опций: в разделе о командных оболочках будет показано, что соответствующей настройкой последних можно добиться любого "умолчального" вывода команды ls
.
Существуют и другие команды для получения информации о файлах. Например, команда под характерным именем file
(единственная в одноименном наборе) с аргументом в виде имени файла в состоянии определить тип его с большой детальностью. Так, для регулярных файлов она распознает:
- исполняемые бинарные файлы с указанием их формата (например, ELF), архитектуры процессора, для которых они скомпилированы, характер связи с разделяемыми библиотеками (статический или динамический)
- исполняемые сценарии с указанием оболочки, для которой они созданы;
- текстовые и html-документы, часто с указанием используемого набора символов.
Последнему, впрочем, для русскоязычных документов доверять особо не следует: кодировка KOI8-R в них вполне может быть обозвана ISO-8859.
Определяет она также каталоги, символические ссылки, специальные файлы устройств, указывая для последних старшие и младшие номера устройств.
Наконец, команда stat
(и это - встроенная команда оболочки), с именем файла в качестве аргумента, выводит большую часть существенных сведений о файле в удобном для восприятия виде, например, включая идентификатор inode
, режим доступа (в символьной форме), идентификаторы владельца и группы, временные атрибуты, количество жестких и символических ссылок.
Приведенных способов получения информации о файле, как кажется, пользователю должно быть достаточно. Перейдем к манипуляциям с существующими файлами - копированию, перемещению, переименованию, удалению.
Манипулирование файлами
Манипулирование файлами осуществляется командами, входящими в состав набора coreutils
.
Начнем с копирования - это выполняется очень простой командой, cp
, имеющей, однако, весьма разнообразные аспекты применения. В самом простом своем виде она требует всего двух аргументов - имени файла-источника на первом месте и имени целевого файла - на втором:
$ cp file_source file_target
Этим в текущем каталоге создается новый файл (file_target
), идентичный по содержанию копируемому (file_source
). То есть область данных первого будет дублировать таковую последнего. Однако области метаданных у них будут различны изначально. Целевой файл - это именно новый файл, со своим идентификатором inode
, заведомо иными временными атрибутами; его атрибуты доступа и принадлежности в общем случае также не обязаны совпадать с таковыми файла-источника.
Новый файл может быть создан и в произвольном каталоге, к которому пользователь имеет соответствующий доступ: для этого следует только указать полный путь к нему:
$ cp file_source dir/subdir/file_target
Если в качестве второго аргумента команды указано просто имя каталога, то новый файл будет создан в нем с именем, идентичным имени файла-источника. Однако подчеркну, что в любом случае копирования создается именно новый файл, никак после этого не связанный с файлом исходным.
Если в качестве последнего аргумента выступает имя каталога, он может предваряться любым количеством аргументов - имен файлов:
$ cp file1 file2 ... file3 dir/
В этом случае в целевом каталоге dir/
будут созданы новые файлы, идентичные по содержанию файлам file1
, file2
и т.д.
Если в целевом (или текущем) каталоге уже имеется файл с именем, совпадающим с именем вновь создаваемого файла, он в общем случае будет без предупреждения заменен новым файлом. Единственное средство для предотвращения этого - задание опции -i
(от interactive) - при ее наличии последует запрос на перезапись существующего файла:
$ cp -i file1 file2
overwrite file2? (y/n [n])
Как было показано в разделе о командных оболочках, некоторые из них (например, zsh
) могут быть настроены так, чтобы по умолчанию не допускать перезаписи существующих файлов. Однако если такая потребность осознанно возникнет, это можно выполнить с помощью опции -f
(от force). К слову сказать, она также аннулирует действие опции -i
, например, при использовании ее в псевдониме команды cp
.
Имя каталога может выступать и в качестве первого аргумента команды cp
. Однако это потребует опции -R
(иногда допустима и опция -r
- в обоих случаях от recursive). В этом случае второй аргумент также будет воспринят как имя каталога, который не только будет создан при этом, но в нем также будет рекурсивно воспроизведено содержимое каталога источника (включая и вложенные подкаталоги).
При копировании файлов, представляющих собой символические ссылки, они будут преобразованы в регулярные файлы, копирующие содержимое файлов - источников ссылки. Однако при рекурсивном копировании каталогов, содержащих символические ссылки, возможно их воспроизведение в первозданном виде. Для этого вместе с опцией -R
должна быть указана одна из опций -H
или -L
. Однако обе они при отсутствии -R
игнорируются.
Как уже было сказано, создаваемые при копировании целевые файлы по умолчанию получают атрибуты доступа и времени, не зависящие от таковых файла-источника. Обычно они определяются значением переменной umask
, заданной глобально, в профильном файле командной оболочки пользователя (по умолчанию значение umask
обычно - 022
). Однако при желании атрибуты исходного файла можно сохранить в файле целевом - для этого предназначена опция -p
. Разумеется, атрибуты эти будут сохранены только в том случае, это это допустимо целевой файловой системой: не следует ожидать, что атрибуты доступа и принадлежности будут сохранены при копировании на носитель с файловой системой FAT.
Для выполнения операции копирования файла он должен иметь атрибут чтения для пользователя, выполняющего копирование; кроме того, последний должен обладать правом на изменение каталога, в который производится копирование.
Кроме простого копирования файлов, существует команда для копирования с преобразованием - dd
. Обобщенный ее формат весьма прост
$ dd [options]
то есть она просто копирует файл стандартного ввода в файл стандартного вывода, а опции описывают условия преобразования входного потока данных в выходной. Реально основными опциями являются if=file1
, подменяющая стандартный ввод указанным файлов, и of=file2
, проделывающая ту же операцию со стандартным выводом.
А далее - прочие условия преобразования, весьма обильные. Большинство из них принимают численные значения в блоках:
- опции
ibs=n
иobs=n
устанавливают размер блока для входного и выходного потоков,bs=n
- для обоих сразу; - опция
skip=n
указывает, сколько блоков нужно пропустить перед записью входного потока; - опция
count=n
предписывает скопировать из входного потока лишь указанное количество блоков.
Имеется и опция conv=value
, которая преобразует входной поток в соответствие с принятыми значениями, например, из формата ASCII в формат EBCDIC, рекомендуемый для использования в ОС на базе Unix System V.
Сфера применения команды dd
далеко выходит за рамки простого копирования файлов. Например, именно с ее помощью изготавливаются загрузочные дискеты.
В операционках BSD-клана существует еще и команда cpdup
, призванная копировать не просто файлы, а целые файловые системы. В отличие от команды cp
, с ее помощью создается полное зеркало файловой системы или отдельных ее ветвей, с сохранением жестких и символических ссылок, файлов устройств, временных атрибутов и атрибутов доступа файлов и подкаталогов. Одно из назначений этой команды - резервное копирование, и в соответствующей заметке мы рассмотрим это подробнее.
Следующие две часто требуемые файловые операции - переименование и перемещение, - выполняются одной командой, mv
. Она требует минимум двух аргументов - имени источника и целевого имени. Если оба они - имена файлов, происходит переименование первого файла во второй. Если последним аргументом выступает имя уже существующего каталога, то файл или каталог, указанные в качестве первого аргумента, перемещается в каталог назначения. Причем если первый аргумент - файл, между первым и последним аргументами может быть сколько угодно аргументов - имен файлов (но не каталогов).
Как и при копировании, при перемещении и переименовании одноименные файлы, ранее существовавшие в целевом каталоге, затираются, замещаясь файлами-источниками без предупреждения. Чтобы этого не случилось, используется опция -i
, требующая запрос на подтверждение действия. Напротив, опция -f
в принудительном порядке перезаписывает существующий файл.
Операции копирования и перемещения/переименования выглядят сходными, однако по сути своей глубоко различны. Начать с того, что команда mv
не совершает никаких действий с перемещаемыми или переименовываемыми файлами - она модифицирует каталоги, к которым приписаны имена этих файлов. Это имеет два важных следствия. Во-первых, при перемещении/переименовании файлы сохраняют первозданными атрибуты доступа, принадлежности и даже времени изменения метаданных (ctime
) и модификации данных (mtime
) - ведь ни те, ни другие при перемещении/переименовании файла не изменяются.
Во-вторых, для выполнения этих действий можно не иметь никаких вообще прав доступа к файлам - достаточно иметь право на изменение каталогов, в которых они переименовываются или перемещаются: ведь имя файла фигурирует только в составе каталога, и нигде более.
Аналогичный смысл имеет и удаление файлов, выполняемое командой
$ rm filename
в которой аргументов, означающих имена подлежащих удалению файлов, может быть произвольное количество. Как и при перемещении, при этом не затрагиваются ни метаданные, ни данные файлов, а только удаляются их имена из родительских каталогов. И потому для удаления файлов опять же не обязательно иметь какие-либо права в их отношении - достаточно прав на изменение содержащих их каталогов.
Командой rm
файлы-аргументы будут удалены в общем случае без предупреждения. Подобно командам cp
и mv
, для команды rm
предусмотрены опции -i
(запрос на подтверждение) и -f
(принудительное удаление вне зависимости от настроек оболочки).
Интересный момент - удаление случайно созданных файлов с именами, "неправильными" с точки зрения системы или командной оболочки. Примером этого могут быть имена, начинающиеся с символа дефиса. Если попробовать сделать это обычным образом
$ rm -file
в ответ последует сообщение об ошибке типа
rm: illegal option -- l
то есть имя файла будет воспринято как опция. Для предотвращения этого такое "неправильное" имя следует предварить символом двойного дефиса и пробелом, означающими конец списка опций:
$ rm -- -file
В принципе, команда rm
ориентирована на удаление обычных и прочих файлов, но не каталогов. Однако с опцией -d
она в состоянии справиться и с этой задачей - в случае, если удаляемый каталог пуст. Наконец, опция -R
(или -r
) производит рекурсивное удаление каталогов со всеми их файлами и вложенными подкаталогами.
Это делает использование опции -R
весьма опасным: возможно, набивший оскомину пример
$ rm -R /
когда при наличии прав суперпользователя уничтожается вся файловая система, и утрирован, но в локальном масштабе такая операция более чем реальна.
Специально для удаления каталогов предназначена команда
$ rmdir
которая способна удалить только пустой каталог. Кроме того, с опцией -p
она может сделать это и в отношении каталогов родительских - но также только в том случае, если они не содержат файлов.
Архивация и компрессия
Архивация и компрессия - это уже не только манипулирование файлами, но и, некоторых образом, изменение их контента. Тем не менее рассмотрим их в этом разделе - ведь с позиций пользователя их смыл близок копированию файлов. И, собственно, целям резервного копирования и архивация, и компрессия призваны служить.
Для пользователя DOS/Windows, привыкшего к программам типа Zip/WinZip, архивация и компрессия неразрывны, как лошади в упряжке. Однако это - разные действия. Архивация - это сборка группы файлов или каталогов в единый файл, содержащий не только данные файлов-источников, но и информацию о них - имена файлов и каталогов, к которым они приписаны, атрибуты принадлежности, доступа и времени, что позволяет восстановить как данные, так и их структуру из архива в первозданном виде. Компрессия же предназначена исключительно для уменьшения объема, занимаемого файлами на диске (или ином носителе).
Для архивации и компрессии предназначены самостоятельные команды. Хотя архивацию и компрессию можно объединить в одной конструкции или представить так, будто они выполняются как бы в едином процессе.
Традиционные средства архивации Unix-систем - команды cpio
и tar
. Суть первой, как можно понять их названия - копирование файлов в файл архива и из файла архива. Используется она в трех режимах.
Первый режим, copy-out, определяемый опцией -o
(или --create
), предусматривает считывание списка файлов (name list) со стандартного ввода и объединяет их в архив, который может быть направлен в архивный файл или на устройство для записи резервных копий. Список файлов для архивирования может представлять собой вывод какой-либо иной команды. Так, в примере
$ find ./* | cpio -o > arch.cpio
файлы текущего каталога, найденные командой find
, при посредстве команды cpio
будут направлены в архивный файл arch.cpio
.
Второй режим (copy-in, опция -i
, или --extract
) осуществляет обратную процедуру: развертывание ранее созданного архива в текущем каталоге:
$ cpio -i <>
Здесь нужно заметить, что если разворачиваемый архив включает подкаталоги, автоматически они созданы не будут, и последует сообщение об ошибке. Для создания промежуточных каталогов команда cpio
должна использоваться с опцией -d
(--make-directories
).
В третьем режиме (copy-pass, опция -p
, или --pass-through
) команда cpio
выполняет копирование файлов из одного дерева каталогов в другой, комбинируя режимы copy-out и copy-in, но без образования промежуточного архива. Список файлов для копирования (name list) считывается со стандартного ввода, а каталог назначения указывается в качестве аргумента:
$ cpio -p dir2 <>
Команда cpio
имеет множество опций, позволяющих создавать, в частности, архивы в различных форматах (для межплатформенной переносимости). Однако я на них останавливаться не буду, отсылая заинтересованных к соответствующей man-странице: она не кажется мне удобной в применении. И упомянута здесь, во-первых, для полноты картины, во-вторых - универсальности ранее (архивы cpio
понимаются абсолютно всеми Unix'ами), в третьих - как одно из средств преобразования пакетов, используемых в различных дистрибутивах Linux, друг в друга. Например, утилита rpm2cpio
преобразует широко распространенный формат пакетов rpm
в еще более универсальный cpio
.
Основным же средством архивирования во всех Unix-системах является команда tar
. Обобщенный формат ее -
$ tar [options] archiv_name [arguments]
где archiv_name
- обязательный аргумент, указывающий на имя архивного файла, с которым производятся действия, определяемые главными опциями. Формы указания опций для команды tar
очень разнообразны. Исторически первой была краткая форма без предваряющего дефиса, что поддерживается и поныне. Однако в текущих версиях команды в целях единообразия утверждена краткая форма с предваряющим дефисом или дублирующая ее полная форма, предваряемая двумя дефисами. Некоторые опции (например --help
- получение справки об использовании команды) предусмотрены только в полной форме.
Главные опции и указывают на то, какие действия следует выполнить над архивом в целом:
- создание архива (опция
c
,-c
или--create
); - просмотр содержимого существующего архива (опция
t
,-t
или--list
); - распаковка архива (опция
x
,-x
,--extract
или--get
).
Легко понять, что при работе с архивом как целым одна из этих главных (т.н. функциональных) опций обязательна. При манипулировании же фрагментами архива они могут подменяться другими функциональными опциями, как то:
r
(-r
или--append
) - добавление новых файлов в конец архива;u
(-u
или--update
) - обновление архива с добавлением не только новых, но и модифицированных (с меньшим значением атрибутаmtime
) файлов;-A
(--catenate
или--concatenate
) - присоединение одного архива к другому;--delete
- удаление именованных файлов из архива;--compare
- сравнение архива с его источниками в файловой системе.
Прочие (очень многочисленные) опции можно отнести в разряд дополнительных - они определяют условия выполнения основных функций команды. Однако одна из таких дополнительных опций - f
(-f
или --file
), значение которой - имя файла (в том числе файла устройства, и не обязательно на локальной машине), также является практически обязательной. Дело в том, что команда tar
(от tape archiv) изначально создавалась для прямого резервного копирования на стриммерную ленту, и именно это устройство подразумевается в качестве целевого по умолчанию. Так что если это не так (а в нынешних условиях - не так почти наверняка), имя архивного файла в качестве значения опции f
следует указывать явно. Причем некоторые реализации команды tar
требуют, чтобы в списке опций она стояла последней.
Проиллюстрируем сказанное несколькими примерами. Так, архив из нескольких файлов текущего каталога создается следующим образом:
$ tar cf arch_name.tar file1 ... file#
Если задать дополнительную опцию v
, ход процесса будет отображаться на экране - это целесообразно, и в дальнейших примерах эта опция будет использоваться постоянно.
С помощью команды tar
можно заархивировать и целый каталог, включая его подкаталоги любого уровня вложенности, причем - двояким образом. Так, если дать команду
$ tar cvf arch_name.tar *
файлы каталога текущего каталога (включая подкаталоги) будут собраны в единый архив, но без указания имени каталога родительского. А командой
$ tar cvf arch_name.tar dir
каталог dir
будет упакован с полным сохранением его структуры.
С помощью команды
$ tar xvf arch_name.tar
будет выполнена обратная процедура - распаковка заархивированных файлов в текущий каталог. Если при архивировании в качестве аргумента было указано имя каталога, а не набора файлов (пусть даже в виде шаблона) - этот каталог будет восстановлен в виде корневого для всех разархивируемых файлов.
При извлечении файлов из архива никто не обязывает нас распаковывать весь архив - при необходимости это можно сделать для одного нужного файла, следует только указать его имя в качестве аргумента:
$ tar xvf arch_name.tar filename
Правда, если искомый файл находился до архивации во вложенном подкаталоге, потребуется указать и путь к нему - от корневого для архива каталога, который будет различным для двух указанных схем архивации. Ну а для просмотра того, каким образом был собран наш архив, следует воспользоваться командой
$ tar tf arch_name.tar
Если архив собирался по первой схеме (с именами файлов в качестве аргументов, вывод ее будет примерно следующим:
dir2/
dir2/file1
example
new
newfile
tee.png
При втором способе архивации мы увидим на выводе нечто вроде
dir1/
dir1/example
dir1/new
dir1/newfile
dir1/tee.png
dir1/dir2/
dir1/dir2/file1
В данном примере опция v была опущена. Включение ее приведет к тому, что список файлов будет выведен в длинном формате, подобном выводу команды ls -l
:
drwxr-xr-x alv/alv 0 10 май 11:03 2002 dir2/
-rw-r--r-- alv/alv 0 10 май 11:03 2002 dir2/file1
...
Команда tar
имеет еще множество дополнительных опций, призванных предотвращать перезапись существующих файлов, осуществлять верификацию архивов, учитывать при архивации разного рода временные атрибуты, вызывать для исполнения другие программы. К некоторым опциям я еще вернусь после рассмотрения команд компрессии, другие же предлагается изучить самостоятельно, воспользовавшись страницей экранной документации.
Команд для компрессии файлов несколько, но реальный интерес ныне представляют две парные утилиты - gzip/gunzip и bz2/bunzip2. Первый член каждой пары, как легко догадаться из названия, отвечает преимущественно за компрессию, второй - за декомпрессию файлов (хотя посредством должных опций они легко меняются ролями).
Команда gzip
- это традиционный компрессор Unix-систем, сменивший в сей роли более старую утилиту compress
. Простейший способ ее использования -
$ gzip filename
где в качестве аргументов будет выступать имя файла. При этом (внимание!) исходный несжатый файл подменяется своей сжатой копией, которой автоматически присваивается расширение *.gz
.
В качестве аргументов может выступать и произвольное количество имен файлов - каждый из них будет заменен сжатым файлом *.gz
. Более того, посредством опции -r
может быть выполнено рекурсивное сжатие файлов во всех вложенных подкаталогах. Подчеркну, однако, что никакой архивации команда gzip
не производит, обрабатывая за раз только единичный файл. Фактически форма
$ gzip file1 file2 ... file#
просто эквивалент последовательности команд
$ gzip file1
$ gzip file2
...
$ gzip file#
Правда, объединение компрессированных файлов возможно методом конкатенации (с помощью команды cat
) или посредством архивирования командой tar
- и о том, и о другом будет сказано чуть позже.
Команда gzip
имеет и другие опции, указываемые в краткой (однобуквенно) или полной нотации. В отличие от tar
, знак дефиса (или, соответственно, двойного дефиса) обязателен в обоих случаях. Так, опциями -1
... -9
можно задать степень сжатия и, соответственно, время процедуры: -1
соответствует минимальному, но быстрому сжатию, -9
- максимальному, но медленному. По умолчанию в команде gzip
используется опция -6
, обеспечивающая компромисс между скоростью и компрессией.
Благодаря опции -d
(--decompress
) команда gzip может выполнить развертывание сжатого файла, заменяя его оригиналом без расширения *.gz
. Хотя в принципе для этого предназначена команда gunzip
:
$ gunzip file.gz
Использование этой команды настолько прозрачно, что я задерживаться на ней не буду.
В последнее время широкое распространение получил компрессор bzip2
, обеспечивающий большую (на 10-15%) степень сжатия, хотя и менее быстродействующий. Использование его практически идентично gzip
, с деталями его можно ознакомиться с помощью страницы экранной документации man bzip2
. Итоговый компрессированный файл получает имя вида *.bz2
и может быть распакован командой bunzip2
(или командой bzip2 -d
). Следует только помнить, что форматы *.gz
и *.bz2
не совместимы между собой. Соответственно, первый не может быть распакован программой bunzip2
, и наоборот.
Поскольку программы tar
и gz
обеспечивают каждая свою сторону обработки файлов, возникает резонное желание использовать их совместно. Самый простой способ сделать это - воспользоваться командой tar
с опцией z
. Например, команда
$ tar cvzf dir.tar.gz dir/
Обратите внимание, что расширение *.gz
в этом случае нужно указывать в явном виде - автоматически оно к имени архива не присоединяется и компрессированный архив будет иметь вид dir.tar
. Поскольку в Unix расширения имен файлов не играют той сакральной роли, что в MS DOS, это не помешает распаковке такого файла командой
$ tar xvzf dir.tar
Опция z
сама по себе никакой компрессии не выполняет - она просто вызывает компрессор gzip
для сжатия каждого из архивируемых файлов. Аналогичный смысл имеет и опция j
- только ею для этой цели привлекается команда bzip2
.
При использовании команды tar
с опцией z
(или j
) исходные файлы остаются в неприкосновенности. Следует, однако, помнить, что архив сжатых файлов не может быть обновлен командой tar
с параметрами r
или u
.
Есть и другой способ совместной архивации и компрессии - просто последовательность команд
$ tar cf dir.tar *
$ gzip dir.tar
В результате образуется сжатый архив - внешне такой же файл dir.tar.gz
. Хотя в принципе архив сжатых файлов и сжатый архивный файл - это разные вещи (можно заметить, что они даже различаются по объему, хотя и всего на несколько байт), сжатый архив также может быть благополучно развернут командой tar
с опцией z
. И столь же очевидно, что он не может быть ни пополнен, ни обновлен средствами архиватора tar
.
Компрессированные архивы, созданные сочетанием программ tar
и gzip
/bzip2
- общепринятый в Unix-системах метод распространения файлов. Однако иногда для совместимости с ОС, не допускающими двух точек в имени файла (знаете такую ОС?), компрессированным tar-архивам на присваивается расширение *.tgz
. Можно встретить и файлы с маской *.tbz2
(или даже *.tbz
- именно такой вид имеют пакеты в 5-й ветке FreeBSD). Нетрудно догадаться, что это те же архивы *.tar.bz2
.