В этом отрывке рассмотрены жесткие и символические ссылки, а также разобрано удаление файлов и директорий с помощью команд rm и rmdir.
Создание ссылок и удаление файлов
Жесткие ссылки
Мы уже упоминали термин «ссылка», когда рассказывали о взаимоотношениях между директориями (их именами) и инодами (индексным номерами, лежащими в основе файловой системы, которых мы не замечаем). Вообще в Linux существует два типа ссылок. Тип, о котором мы уже говорили ранее, называется «жесткие ссылки». Каждый инод может иметь произвольное число жестких ссылок. Когда уничтожается последняя жесткая ссылка, и не одна программа не держит файл открытым, то Linux автоматически удаляет его. Новые жесткие ссылки можно создать воспользовавшись командой ln:
$ cd /tmp
$ touch firstlink
$ ln firstlink secondlink
$ ls -i firstlink secondlink
15782 firstlink 15782 secondlink
Как видите, жесткие ссылки работают на уровне инодов, для указания конкретного файла. В Linux системах, для жестких ссылок есть несколько ограничений. В частности, можно создавать жесткие ссылки только на файлы, не на директории. Да-да, именно так; хотя "." и ".." являются созданными системой жесткими ссылками на директории, вам (даже от имени пользователя «root») не разрешается создавать любые свои собственные. Второе ограничение жестких ссылок состоит в том, что нельзя связать ими несколько файловых систем. Это значит, что у вас не получится создать жесткую ссылку с /usr/bin/bash на /bin/bash и если ваши директории / и /usr находятся в разных файловых системах (разделах — прим. пер.).
Символьные ссылки
В практике, символьные ссылки (или символические, иногда «симлинки» — от англ.) используются гораздо чаще, чем жесткие. Симлинки — это файлы особого типа, которые ссылаются на другие файлы по имени, а не прямо по номеру инода. Они не спасают файлы от удаления; если файл, на который указывает ссылка, исчезает, то симлинк перестает работать, ломается.
Символические ссылки можно создать передав для ln опцию -s.
$ ln -s secondlink thirdlink
$ ls -l firstlink secondlink thirdlink
-rw-rw-r-- 2 agriffis agriffis 0 Dec 31 19:08 firstlink
-rw-rw-r-- 2 agriffis agriffis 0 Dec 31 19:08 secondlink
lrwxrwxrwx 1 agriffis agriffis 10 Dec 31 19:39 thirdlink -> secondlink
В выводе ls -l символьные ссылки можно отличить тремя способами. Во-первых, обратите внимание на символ l в первой колонке. Во-вторых, размер символической ссылки равен количеству символов в ней (secondlink в нашем случае). В-третьих, последняя колонка в выводе показывает куда ведет ссылка с помощью интуитивного обозначения "->".
Симлинки детально
Символические ссылки в целом более гибкие, чем жесткие. Вы можете создавать символьные ссылки на любой объект файловой системы, включая директории. И благодаря тому, что их реализация основана на путях (не инодах), можно совершенно свободно создать символьную ссылку указывающую на объект другой файловой системы. Однако, сей факт также делает их сложными в понимании.
Предположим, что мы хотим создать ссылку в /tmp, которая указывает на /usr/local/bin. Нам следует набрать:
$ ln -s /usr/local/bin bin1
$ ls -l bin1
lrwxrwxrwx 1 root root 14 Jan 1 15:42 bin1 -> /usr/local/bin
Либо, альтернативный вариант:
$ ln -s ../usr/local/bin bin2
$ ls -l bin2
lrwxrwxrwx 1 root root 16 Jan 1 15:43 bin2 -> ../usr/local/bin
Как вы видите, обе символические ссылки указывают на одну директорию. Однако, если наша вторая символьная ссылка когда-нибудь будет перемещена в другую директорию, то она может «поломаться» из-за относительности пути:
$ ls -l bin2
lrwxrwxrwx 1 root root 16 Jan 1 15:43 bin2 -> ../usr/local/bin
$ mkdir mynewdir
$ mv bin2 mynewdir
$ cd mynewdir
$ cd bin2
bash: cd: bin2: No such file or directory
Потому, что директории /tmp/usr/local/bin не существует, мы больше не можем переместиться в bin2; другими словами, bin2 сейчас сломана.
По этой причине, избегать создания ссылок с относительной информацией о пути, иногда будет хорошей идеей. Тем не менее, существует множество случаев, где относительные символические ссылки крайне удобны. Рассмотрим пример в котором мы хотим создать альтернативное имя для программы в /usr/bin:
# ls -l /usr/bin/keychain
-rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/bin/keychain
От имени суперпользователя мы хотим короткий синоним для keychain, такой, как kc. В этом примере у нас есть root-доступ, о чем свидетельствует измененное на "#" приветствие bash. Нам нужен root-доступ потому, что обычные пользователи не имеют прав создавать файлы в /usr/bin. От имени суперпользователя мы можем создать альтернативное имя для keychain следующим образом:
# cd /usr/bin
# ln -s /usr/bin/keychain kc
# ls -l keychain
-rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/bin/keychain
# ls -l kc
lrwxrwxrwx 1 root root 17 Mar 27 17:44 kc -> /usr/bin/keychain
В этом примере мы создали символьную ссылку под названием kc, которая указывает на файл /usr/bin/keychain.
Пока это решение будет работать, но создаст проблему, если мы решим переместить оба файла, /usr/bin/keychain и /usr/bin/kc в /usr/local/bin:
# mv /usr/bin/keychain /usr/bin/kc /usr/local/bin
# ls -l /usr/local/bin/keychain
-rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/local/bin/keychain
# ls -l /usr/local/bin/kc
lrwxrwxrwx 1 root root 17 Mar 27 17:44 kc -> /usr/bin/keychain
Поскольку мы использовали абсолютный путь для символической ссылки kc, то она все еще ссылается на /usr/bin/keychain, которого не существует с тех пор как мы переместили /usr/bin/keychain в /usr/local/bin.
Это привело к тому, что симлинк kc сейчас не работает. Как относительные, так и абсолютные пути в символьных ссылках имеют свои достоинства, и, в зависимости от вашей задачи, нужно использовать соответствующий тип пути. Часто, и относительный, и абсолютный путь, будут работать одинаково хорошо. Пример ниже будет работать, даже после перемещения обоих файлов:
# cd /usr/bin
# ln -s keychain kc
# ls -l kc
lrwxrwxrwx 1 root root 8 Jan 5 12:40 kc -> keychain
# mv keychain kc /usr/local/bin
# ls -l /usr/local/bin/keychain
-rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/local/bin/keychain
# ls -l /usr/local/bin/kc
lrwxrwxrwx 1 root root 17 Mar 27 17:44 kc -> keychain
Теперь, мы можем запустить программу keychain набрав /usr/local/bin/kc. /usr/local/bin/kc указывает на программу keychain в той же директории, где находится kc.
rm
Итак, мы знаем как использовать cp, mv и ln, настало время узнать о том, как можно удалять объекты из файловой системы. Обычно это делается с помощью команды rm. Чтобы удалить файлы, просто укажите их в командной строке:
$ cd /tmp
$ touch file1 file2
$ ls -l file1 file2
-rw-r--r-- 1 root root 0 Jan 1 16:41 file1
-rw-r--r-- 1 root root 0 Jan 1 16:41 file2
$ rm file1 file2
$ ls -l file1 file2
ls: file1: No such file or directory
ls: file2: No such file or directory
Имейте ввиду, что под Linux, однажды удаленный файл, обычно исчезает на века. Поэтому многие начинающие системные администраторы используют опцию -i, когда удаляют файлы. Опция -i сообщает rm удалять файлы в интерактивном режиме — это значит спрашивать перед удалением любого файла. Например:
$ rm -i file1 file2
rm: remove regular empty file `file1'? y
rm: remove regular empty file `file2'? y
В примере выше команда rm запрашивает подтверждение на удаление каждого из указанных файлов. В случае согласия, я должен был вводить «y» и нажать enter, дважды. Если бы я ввел «n», то файл бы остался цел. Или, если я сделал что-нибудь не так, я мог бы нажать Control-C и сбросить выполнение команды rm -i целиком — всяко до того, как это могло нанести какой-нибудь ущерб моей системе.
Если вы все еще учитесь пользоваться командой rm, то может быть полезным добавить при помощи вашего любимого текстового редактора следующую строку в ваш файл ~/.bashrc, и затем выйти (logout) и войти (login) в систему вновь. После этого, всякий раз, когда вы наберете rm, оболочка bash преобразует ее автоматически в команду rm -i. Таким образом, rm будет всегда работать в интерактивном режиме:
alias rm="rm -i"
rmdir
Для удаления директорий у вас имеется два варианта. Вы можете удалить все объекты внутри директории и затем воспользоваться rmdir для удаления самой директории:
$ mkdir mydir
$ touch mydir/file1
$ rm mydir/file1
$ rmdir mydir
Этот метод широко известен под названием «способ удаления директорий для лохов». Все реальные пацаны и админы-гуру съевшие пользователя собаку на этом деле, используют гораздо более удобную команду rm -rf, описанную далее.
Самый лучший способ удалить директорию состоит в использовании опций «рекурсивного принуждения» (recursive force) команды rm, чтобы приказать ей удалять указанную директорию, также как и объекты содержащиеся внутри:
$ rm -rf mydir
Обычно, rm -rf является наиболее предпочтительным методом для удаления древа директорий. Будьте очень осторожны, когда пользуетесь rm -rf, так как ее мощь может быть использована по обе стороны: добра и зла. =)
Продолжение...
Об авторах
Daniel Robbins
Дэниэль Роббинс — основатель сообщества Gentoo и создатель операционной системы Gentoo Linux. Дэниэль проживает в Нью-Мехико со свой женой Мэри и двумя энергичными дочерьми. Он также основатель и глава Funtoo, написал множество технических статей для IBM developerWorks, Intel Developer Services и C/C++ Users Journal.
Chris Houser
Крис Хаусер был сторонником UNIX c 1994 года, когда присоединился к команде администраторов университета Тэйлора (Индиана, США), где получил степень бакалавра в компьютерных науках и математике. После он работал во множестве областей, включая веб-приложения, редактирование видео, драйвера для UNIX и криптографическую защиту. В настоящий момент работает в Sentry Data Systems. Крис также сделал вклад во множество свободных проектов, таких как Gentoo Linux и Clojure, стал соавтором книги The Joy of Clojure.
Aron Griffis
Эйрон Гриффис живет на территории Бостона, где провел последнее десятилетие работая в Hewlett-Packard над такими проектами, как сетевые UNIX-драйвера для Tru64, сертификация безопасности Linux, Xen и KVM виртуализация, и самое последнее — платформа HP ePrint. В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».