Основы Linux, часть 1

Danial Robbins

Прежде, чем начать

Об этом руководстве

Добро пожаловать в "Основы Linux", первое из четырех руководств, предназначенных для подготовки к экзамену LPI-101 (Linux Professional Institute). В этом руководстве мы познакомим вас с bash (стандартной оболочкой Linux), покажем как использовать такие стандартные команды, как ls, cp и mv, объясним, что такое индексный дескриптор inode, жесткие и символьные ссылки и многое другое. К концу руководства вы получите солидные знания основ Linux и даже будете готовы начать изучение некоторых основных задач администрирования системы Linux. К концу этой серии руководств (всего восемь) вы получите знания, нужные для того, чтобы стать системным администратором Linux и будете готовы получить сертификат LPIC первого уровня в выбранном вами Linux Professional Institute.

Именно это руководство (Часть 1) идеально для тех, кто знакомится с Linux впервые, или тех, кто хочет освежить или улучшить свое понимание основных концепций Linux, таких как копирование или перемещение файлов, создание символических и жестких ссылок и использование стандартных команд обработки текста вместе с конвейерами и перенаправлением. На этом пути мы поделимся множеством советов, намеков и трюков, делая руководство содержательным и практичным даже для тех, кто имеет некоторый опыт предыдущей работы с Linux. Для новичков большая часть материала будет новой, но более опытные пользователи Linux могут найти в этом руководстве хороший способ пополнить свое знание основ Linux.

Тем, кто пользовался первой версией этого руководства для целей, отличных от подготовки к экзаменам LPI, вероятно нет необходимости использовать эту версию. Однако, если вы планируете сдавать экзамены, чтение этого пересмотренного руководства настоятельно рекомендуется.

Введение в bash

Оболочка

Если вы используете Linux, вы знаете, что зарегистрировавшись вы получите приглашение с подсказкой, которая выглядит так:

$

Конкретная подсказка, которую вы увидите, может выглядеть совсем по-другому. Она может содержать сетевое имя вашей системы, имя текущей рабочей директории или и то, и другое. Но несмотря на то, как выглядит ваша подсказка, одно несомненно, программа, которая выводит эту подсказку, называется "shell" (оболочка), и очень вероятно, что ваша индивидуальная оболочка это программа, которая называется 'bash'.

Выполняется bash?

Вы можете проверить, выполняется у вас 'bash' набрав:

$ echo $SHELL
/bin/bash

Если вышеприведенная строка содержит сообщение об ошибке или ответ не похож на наш пример, то вы, наверное, используете оболочку, отличную от bash. В этом случае большая часть руководства остается применимой, но в целях подготовке к экзамену LPI-101 было бы полезно переключиться на 'bash'.

О bash

Bash, акроним "Bourne-again shell," оболочка, которая выполняется по умолчанию в большинстве систем Linux. Работа оболочки заключается в том, чтобы выполнять ваши команды, таким образом вы можете взаимодействовать с вашей системой Linux. Когда вы закончите ввод команд, вы можете дать команду оболочке выйти или завершить сеанс, и вы вернетесь к экрану регистрации.

Кстати, вы можете завершить сеанс, нажав в приглашении bash control-D.

Использование "cd"

Как вы вероятно уже поняли, разглядывание приглашения вашей оболочки не самое волнующее в этом мире. Давайте начнем использовать bash для путешествия по нашей файловой системе. После подсказки наберите следующее (без '$'):

$ cd /

Вы только что сказали bash, что вы хотите работать в /, известной также как корневая директория; все директории в системе образуют дерево, и / рассматривается как вершина этого дерева, или корень. cd устанавливает директорию, где вы в настоящее время работаете, которая называется "текущая рабочая директория".

Пути

Чтобы посмотреть текущую рабочую директорию bash, вы можете набрать:

$ pwd
/

В вышеприведенном пример / это аргумент 'cd', он называется путь. Он указывает cd, куда мы хотим перейти. В частности, аргумент / это абсолютный путь, подразумевающий, что он указывает положение относительно корня дерева файловой системы.

Абсолютные пути

Вот некоторые другие абсолютные пути:

/dev
/usr
/usr/bin
/usr/local/bin

Как вы можете видеть, единственная вещь, которая есть у всех абсолютных путей, это то, что они начинаются с /. Задавая путь /usr/local/bin, мы говорим cd войти в директорию /, затем в этой директории в директорию usr, затем local, а затем bin. Абсолютные пути всегда вычисляются начиная с /.

Относительные пути

Другая разновидность пути называется относительным путем. 'Bash' , 'cd' , и другие команды всегда интерпретируют эти пути относительно текущей директории. Относительные пути никогда не начинаются с /. Итак, если мы в /usr:

$ cd /usr

То мы можем использовать относительный путь, чтобы сменить директорию на /usr/local/bin:

$ cd local/bin
$ pwd
/usr/local/bin

Использование ..

Относительные пути могут содержать также одни или более .. директории. Директория .. это специальная директория, которая указывает на родительскую директорию. Так, продолжая предыдущий пример:

$ pwd
/usr/local/bin
$ cd ..
$ pwd
/usr/local

Как можно видеть, наши текущая директория теперь /usr/local. Мы смогли вернуться "назад" на одну директорию относительно текущей директории, в которой мы были.

Вдобавок мы можем также добавить .. к существующему относительному пути, что дает нам возможность перейти в директорию, которая находится рядом с директорией, в которой мы уже находимся, например:

$ pwd
/usr/local
$ cd ../share
$ pwd
/usr/share

Примеры относительных путей

Относительный пути могут быть довольно сложными. Вот несколько примеров, во всех результирующая целевая директория не выводится. Попытайтесь понять, где вы окажетесь после набора этих команд:

$ cd /bin
$ cd ../usr/share/zoneinfo


$ cd /usr/X11R6/bin
$ cd ../lib/X11


$ cd /usr/bin
$ cd ../bin/../bin

Теперь проверьте их и посмотрите, правильно ли вы их получили :)

Что такое .

Прежде чем закончить наше знакомство с cd, я должен упомянуть еще несколько вещей. Во-первых, есть еще одна специальная директория, которая называется ., что подразумевает "текущую директорию". Поскольку эта директория обычно не используется с командой cd, она используется для того, чтобы выполнить команду в текущей директории, например:

$ ./myprog

В этом примере будет выполняться myprog, исполняемая программа, размещающаяся в текущей рабочей директории.

cd и домашняя директория

если мы хотим перейти в нашу домашнюю директорию, мы можем набрать:

$ cd

Без аргументов cd перейдет в вашу домашнюю директорию, /root для суперпользователя или, как правило, /home/username для обычного пользователя. Но что если мы хотим указать файл в нашей домашней директории? Может быть мы хотим передать файл аргументом команде 'myprog'. Если файл живет в нашей домашней директории, мы можем набрать:

$ ./myprog /home/drobbins/myfile.txt

Однако использование абсолютного пути подобно этому не всегда удобно. К счастью, мы может использовать символ ~ (тильду), чтобы сделать то же самое:

$ ./myprog ~/myfile.txt

Домашние директории других пользователей

Bash раскроет отдельный ~ в указатель на вашу домашнюю директорию, но вы можете использовать его также и для указателя на домашнюю директорию других пользователей. Например, если мы хотим сослаться на файл с именем fredsfile.txt в домашней директории пользователя fred, мы можем набрать:

$ ./myprog ~fred/fredsfile.txt

Использование команд Linux

Введение в ls

Теперь посмотрим на команду ls. Очень вероятно вы уже знакомы с ls и знаете, что ввод ее выдаст список содержимого текущей рабочей директории:

$ cd /usr
$ ls
X11R6      doc         i686-pc-linux-gnu  lib      man          sbin   ssl
bin        gentoo-x86  include            libexec  portage      share  tmp
distfiles  i686-linux  info               local    portage.old  src

Указав опцию -a, вы можете увидеть все файлы в директории, включая скрытые файлы, те, которые начинаются с '.'. Как можно увидеть в следующем примере, ls -a покажет специальные ссылки на директории '.' и '..':

$ ls -a
.      bin        gentoo-x86         include  libexec  portage      share  tmp
..     distfiles  i686-linux         info     local    portage.old  src
X11R6  doc        i686-pc-linux-gnu  lib      man      sbin         ssl

Длинные листинги директорий

Вы можете также указать один или более файлов или директорий в командной строке 'ls'. Если вы укажете файл, 'ls' покажает только этот файл. Если вы укажете директорию, 'ls' покажет содержимое директории. Опция '-l' оказывается очень удобной, если вам нужно в вашем листинге директории нужно видеть информацию о правах, собственнике, времени модификации и размере.

В следующем примере мы используем опцию '-l', чтобы вывести полный листинг моей директории /usr.

$ ls -l /usr
drwxr-xr-x    7 root     root          168 Nov 24 14:02 X11R6
drwxr-xr-x    2 root     root        14576 Dec 27 08:56 bin
drwxr-xr-x    2 root     root         8856 Dec 26 12:47 distfiles
lrwxrwxrwx    1 root     root            9 Dec 22 20:57 doc -> share/doc
drwxr-xr-x   62 root     root         1856 Dec 27 15:54 gentoo-x86
drwxr-xr-x    4 root     root          152 Dec 12 23:10 i686-linux
drwxr-xr-x    4 root     root           96 Nov 24 13:17 i686-pc-linux-gnu
drwxr-xr-x   54 root     root         5992 Dec 24 22:30 include
lrwxrwxrwx    1 root     root           10 Dec 22 20:57 info -> share/info
drwxr-xr-x   28 root     root        13552 Dec 26 00:31 lib
drwxr-xr-x    3 root     root           72 Nov 25 00:34 libexec
drwxr-xr-x    8 root     root          240 Dec 22 20:57 local
lrwxrwxrwx    1 root     root            9 Dec 22 20:57 man -> share/man
lrwxrwxrwx    1 root     root           11 Dec  8 07:59 portage -> gentoo-x86/
drwxr-xr-x   60 root     root         1864 Dec  8 07:55 portage.old
drwxr-xr-x    3 root     root         3096 Dec 22 20:57 sbin
drwxr-xr-x   46 root     root         1144 Dec 24 15:32 share
drwxr-xr-x    8 root     root          328 Dec 26 00:07 src
drwxr-xr-x    6 root     root          176 Nov 24 14:25 ssl
lrwxrwxrwx    1 root     root           10 Dec 22 20:57 tmp -> ../var/tmp

Первая колонка выводит информацию о правах для каждого пункта в списке. Я объясню, как интерпретировать эту информацию, через минуту. Следующая колонка содержит число ссылок на каждый объект файловой системы, о чем мы сейчас умолчим, вернемся к этому позже. Третья и четвертая колонки собственника и группу соответственно. Пятая колонка содержит размер объекта. Шестая колонка - время "последней модификации" или "mtime" объекта. Последняя колонка - имя объекта. Если файл представляет собой символьную ссылку, вы увидите сзади -> и путь, на который указывает символьная ссылка.

Просмотр директорий

Иногда вы хотите посмотреть на директорию, а не внутри нее. Для таких ситуаций вы можете указать опцию '-d', которая укажет ls смотреть на любые директории, как если бы они нормально выглядели внутри:

$ ls -dl /usr /usr/bin /usr/X11R6/bin ../share
drwxr-xr-x    4 root     root           96 Dec 18 18:17 ../share
drwxr-xr-x   17 root     root          576 Dec 24 09:03 /usr
drwxr-xr-x    2 root     root         3192 Dec 26 12:52 /usr/X11R6/bin
drwxr-xr-x    2 root     root        14576 Dec 27 08:56 /usr/bin

Рекурсивный листинг и листинг inode

Итак, вы можете использовать '-d', чтобы взглянуть на директорию, но вы можете также использовать '-R' чтобы получить обратное: не только заглянуть внутрь директории, но рекурсивно заглянуть во все файлы и директории внутри этой директории! Мы не будем включать какие-либо примеры вывода с этой опцией (так как они обычно объемисты), но вы можете захотеть попробовать несколько команд 'ls -R' и 'ls -Rl', чтобы почувствовать, как это работает.

Наконец, опцию ls '-i' можно использовать, чтобы вывести номера inode объектов файловой системы в следующий листинг:

$ ls -i /usr
   1409 X11R6        314258 i686-linux           43090 libexec        13394 sbin
   1417 bin            1513 i686-pc-linux-gnu     5120 local          13408 share
   8316 distfiles      1517 include                776 man            23779 src
     43 doc            1386 info                 93892 portage        36737 ssl
  70744 gentoo-x86     1585 lib                   5132 portage.old      784 tmp

Что такое inodes

Каждому объекту файловой системы назначается уникальный индекс, который называется индексным дескриптором inode. Это может показаться тривиальным, но понимание inodes существенно для понимание многих операций файловой системы. Например, рассмотрим ссылки . и .., которые появляются в каждой директории. Чтобы полностью понять, что в действительности представляет директория .., взглянем сначала на номер inode директории /usr/local:

$ ls -id /usr/local
   5120 /usr/local

Директория /usr/local имеет индекс 5120. Теперь давайте взглянем на индекс /usr/local/bin/..:

$ ls -id /usr/local/bin/..
   5120 /usr/local/bin/..

Как вы можете видеть, /usr/local/bin/.. имеет тот же индекс, что и /usr/local! Вот как мы можем начать борьбу с этим потрясающим открытием. В прошлом мы рассматривали /usr/local как саму директорию. Теперь мы обнаружили, что inode 5120, в действительности это директория, и мы нашли два входа для директорий (называемых указателями), которые указывают на этот inode. И /usr/local и /usr/local/bin/.. имеют указатель на inode 5120. Хотя указатель inode 5120 существует только в одном месте на диске, множество объектов ссылаются на него. Inode 5120 это настоящая запись на диске.

Фактически мы можем увидеть общее число ссылок, который ссылаются на inode 5120, воспользовавшись командой 'ls -dl':

$ ls -dl /usr/local
drwxr-xr-x    8 root     root          240 Dec 22 20:57 /usr/local

Если посмотреть на второй слева столбец, можно увидеть, что на директорию /usr/local (inode 5120) ссылаются восемь раз. Вот различные пути, которые ссылаются на этот inode на моей системе:

/usr/local
/usr/local/.
/usr/local/bin/..
/usr/local/games/..
/usr/local/lib/..
/usr/local/sbin/..
/usr/local/share/..
/usr/local/src/..

mkdir

Давайте взглянем на команду mkdir, которую можно использовать для создания новых директорий. Следующий пример создает три новых директории, tic, tac и toe, все в директории /tmp:

$ cd /tmp
$ mkdir tic tac toe

По умолчанию, команда mkdir не создает для вас родительских директорий; весь путь вплоть до предпоследнего элемента должен существовать. Так что, если вы хотите создать директории won/der/ful, вам нужно выдать три отдельные команды 'mkdir':

$ mkdir won/der/ful
mkdir: cannot create directory `won/der/ful': No such file or directory
$ mkdir won
$ mkdir won/der
$ mkdir won/der/ful

Однако у mkdir есть удобная опция -p, которая говорит mkdir создать все отсутствующие родительские директории, как вы можете увидеть здесь:

$ mkdir -p easy/as/pie

В общем, приятно и просто. Чтобы узнать о команде mkdir больше, наберите 'man mkdir' и почитайте страницу руководства man. Это будет работать почти для всех охваченных здесь команд (например, 'man ls' ), за исключением cd, которая встроена в bash.

touch

теперь мы собираемся взглянуть на команды 'cp' и 'mv', используемые для копирования, переименования или перемещения файлов и директорий. Чтобы начать этот обзор, сначала используем команду 'touch' для создания файла в /tmp:

$ cd /tmp
$ touch copyme

Команда touch обновляет "mtime" файла, если он существует (вспомните шестой столбец в выводе 'ls -l'). Если файл не существует, то создается новый пустой файл. Теперь у вас должен быть файл /tmp/copyme с нулевым размером.

echo

Теперь, когда файл существует, давайте добавим в файл данные. Мы можем сделать это с помощью команды echo, которая берет свои аргументы и выводит их в стандартный поток вывода. Сначала команда echo сама по себе:

$ echo "firstfile"
firstfile

Теперь та же команда echo с перенаправлением вывода:

$ echo "firstfile" > copyme

Знак больше-равно приказывает оболочке записать вывод echo в файл с именем copyme. Этот файл будет создан, если он не существует, и будет перезаписан, если нет. Набрав 'ls -l', мы можем видеть, что файл copyme имеет длину 10 байт, так как он содержит слово firstfile и символ новой строки:

$ ls -l copyme
-rw-r--r--    1 root     root           10 Dec 28 14:13 copyme

cat и cp

Чтобы вывести содержимое файла на терминал, используйте команду cat:

$ cat copyme
firstfile

Теперь мы можем использовать основной вызов команды 'cp', чтобы создать файл copiedme из первоначального файла copyme:

$ cp copyme copiedme

В результате расследования мы найдем, что это поистине отдельные файлы; их индексы inode различны:

$ ls -i copyme copiedme
  648284 copiedme   650704 copyme

mv

Теперь давайте используем команду mv, чтобы переименовать "copiedme" в "movedme". Индекс inode останется прежним; однако имя файла, которое указывает на этот inode изменится.

$ mv copiedme movedme
$ ls -i movedme
  648284 movedme

Индекс inode перемещенного файла останется тем же, как и сам файл назначения размечается на той же файловой системе, что и исходный файл. Мы более пристально рассмотрим файловые системы в части 3 этой серии руководств.

Говоря о mv, давайте на другой способ использовать эту команду. В добавок к тому, что она позволяет переименовывать файлы, команда mv позволяет также перемещать один или более файлов в другое место иерархии директорий. Например, чтобы переместить /var/tmp/myfile.txt в /home/drobbins (что как раз является моей домашней директорией), я мог бы набрать:

$ mv /var/tmp/myfile.txt /home/drobbins

После выполнения этой команды myfile.txt будет перемещен в /home/drobbins/myfile.txt. И, если /home/drobbins находится в другой файловой системе, чем /var/tmp, команда mv займется копированием myfile.txt в новую файловую систему и удалением его из старой файловой системы. Как вы могли бы предположить, при перемещении между файловыми системами myfile.txt в новом месте получит новый индекс inode. Потому, что каждая файловая система имеет свое собственное независимое множество индексов inode.

Мы также можем использовать команду mv для перемещения многих файлов в одну директорию назначения. Например, чтобы переместить файлы myfile1.txt и myarticle3.txt в /home/drobbins, я мог бы набрать:

$ mv /var/tmp/myfile1.txt /var/tmp/myarticle3.txt /home/drobbins

Создание ссылок и удаление файлов

Жесткие ссылки

Мы употребляем термин "ссылка", когда говорим о связи между записями директории (мы пишем "имена") и индексами inode (индексы основной файловой системы, которые обычно мы можем игнорировать). На самом деле в Linux доступны два вида ссылок. Вид, который мы обсуждали до сих пор, называется жесткими ссылками. Заданный inode может иметь любое количество жестких ссылок, и inode будет существовать в файловой системе, пока не исчезнут все жесткие ссылки. Когда последняя жесткая ссылка исчезнет и если никакая программа не держит файл открытым, Linux автоматически удалит файл. Новую жесткую ссылку можно создать с помощью команды 'ln':

$ cd /tmp
$ touch firstlink
$ ln firstlink secondlink
$ ls -i firstlink secondlink
  15782 firstlink    15782 secondlink

Как вы можете видеть, жесткая ссылка работает на уровне индексов inode, чтобы указать на отдельный файл. В системах Linux жесткие ссылки имеют несколько ограничений. Первое, вы можете создать жесткую ссылку на файлы, но не на директории. Это так, даже несмотря на то, что . и .. системные жесткие ссылки на директории, вам не разрешается создать свою собственную жесткую ссылку (даже пользователю 'root"). Второе ограничение жестких ссылок состоит в том, что они не могут охватить файловые системы. Это означает, что вы не можете создать ссылку с /usr/bin/bash на /bin/bash, если ваши директории / и /usr существуют на различных файловых системах.

Символьные ссылки

На практике символьные ссылки (или symlinks) используются чаще, чем жесткие ссылки. Символьные ссылки - специальный тип файла, где ссылка отсылает к другому файлу по имени, а не прямо к индексу inode. Символьные ссылки не препятствуют удалению файла, если целевой файл исчезает, то символьная ссылка будет просто не используемой или сломанной.

Символьную ссылку можно создать, передавая опцию -s команде ln.

$ 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', в нашем случае). В-третьих, последняя колонка вывода содержит целевое имя файла, перед которым стоит привлекательный маленький ->.

Символьные ссылки подробнее

Символьные ссылки в целом более гибки, чем жесткие ссылки. Вы можете создать символьную ссылку на объект файловой системы любого типа, включая директории. И поскольку реализация символьных ссылок основана на путях, а не на индексах inode, очень просто создать символьную ссылку на объект другой физической файловой системы. Однако этот факт может сделать символьную ссылку и сложной для понимания.

Рассмотрим ситуацию, когда мы хотим создать ссылку в /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

Как пользователь root вы можете захотеть создать альтернативное имя для "keychain", такое как "kc". В этом примере мы имеем доступ пользователя root, доказательство чему служит изменение подсказки bash на "#". Нам нужен доступ пользователя root, поскольку обычные пользователи не могут создавать файлы в /usr/bin. Будучи root, мы могли бы создать альтернативное имя для 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, как только файл подвергся действию команды rm, он обычно исчезает навсегда. По этой причине молодые системные администраторы используют при удалении файлов опцию -i. Опция -i приказывает rm удалять все файлы в интерактивном режиме, то есть, запрашивать подтверждение перед удалением каждого файла. Например:

$ rm -i file1 file2
rm: remove regular empty file `file1'? y
rm: remove regular empty file `file2'? y

В этом примере команда rm запрашивает, нужно или нет на *самом деле* удалять указанные файлы. Для того чтобы удалить их, я должен дважды набрать "y" и нажать Ввод. Если я наберу "n", файл не будет удаляться. Или, если я сделал что-то не то, я мог бы набрать Control-C, чтобы полностью прекратить выполнение команды rm -i, прежде чем она сделает что-то потенциально опасное для моей системы.

Если вы всеже пользуетесь командной rm, может оказаться полезным добавить с помощью вашего любимого текстового редактора в ваш файл ~/.bashrc следующую строку, а затем выйти из сессии и войти в нее вновь. Тогда каждый раз, когда вы наберете rm, оболочка bash автоматически преобразует ее в команду rm -i. Таким образом, rm всегда будет работать в интерактивном режиме:

alias rm="rm -i"

rmdir

Есть две возможности удалить директории. Вы можете удалить все объекты в директории, а потом использовать 'rmdir', чтобы удалить саму директорию:

$ mkdir mydir
$ touch mydir/file1
$ rm mydir/file1
$ rmdir mydir

Этот метод известен как "удаление директории для молокососов". Все настоящие пользователи и администраторы, заслуживающие свое положение, используют много более удобную команду 'rm -rf', превосходящую rmdir.

Лучший способ удалить директорию - использовать опции рекурсивно принудительно команды rm, чтобы приказать rm удалить указанную директорию, а также все объекты, содержащиеся в директории:

$ rm -rf mydir

Как правило, rm -rf - предпочтительный метод удаления дерева директории. Будьте осторожны при использовании rm -rf, так как ее мощь может служить и богу, и дьяволу :)

Использование шаблонов (Wild cards)

Введение в шаблоны

В повседневном использовании Linux вам много раз потребуется выполнить единственную операцию (такуя как rm) сразу со множеством объектов файловой системы. В таких ситуациях часто бывает обременительно набирать много файлов в командной строке:

$ rm file1 file2 file3 file4 file5 file6 file7 file8

Чтобы решить эту проблему, вы можете воспользоваться встроенной поддержкой шаблонов. Эта поддержка, которая также называется "подстановкой" (globbing, по историческим причинам), позволяет вам указать множество файлов сразу используя шаблоны. Bash и другие команды Linux интерпретируют этот шаблон, просматривая диск и находя все файлы, которые соответствуют ему. Итак, если у вас в текущей директории есть файлы от file1 до file8, вы можете удалить эти файлы набрав:

$ rm file[1-8]

Или если вы просто хотите удалить все файлы с именами, начинающимися с file, а также файл file, вы можете набрать:

$ rm file*

Образец * сопоставим любому символу или последовательности символов и даже отсутствию символов. Конечно, подстановку образцов можно использовать не только для удаления файлов, что можно увидеть в следующем разделе.

Понятие несовпадения

Если вы хотите вывести все объекты файловой системы, которые находятся в /etc и начинаются с g вместе и сам файл g, вы можете набрать:

$ ls -d /etc/g*
/etc/gconf  /etc/ggi  /etc/gimp  /etc/gnome  /etc/gnome-vfs-mime-magic  /etc/gpm  /etc/group  /etc/group-

Теперь, что случится, если вы укажете образец, который не соответствует никакому объекту файловой системы? В следующем примере мы пытаемся вывести все файлы в /usr/bin, которые начинаются с asdf и кончаются jkl, потенциально включая и asdfjkl:

$ ls -d /usr/bin/asdf*jkl
ls: /usr/bin/asdf*jkl: No such file or directory

Вот, что получилось. Обычно, когда мы указываем образец, этот образец соответствует одному или более файлам, расположенным в файловой системе, и bash заменяет образец списком всех соответствующих объектов, разделенным пробелами. Однако когда образец не дает никаких совпадений, bash оставляет аргумент, образец и все остальное, как есть. Таким образом, ls не может найти файл /usr/bin/asdf*jkl и выдает нам ошибку. Действующее здесь правило: подстановка образцов выполняется, только если они соответствуют объектам файловой системы. В противном случае они остаются, как есть, и в точности передаются программе, которую вы вызываете.

Синтаксис образцов: * и ?

Теперь, когда мы посмотрели, как работает подстановка, мы должны взглянуть на синтаксис образов. Вы можете использовать специальные символы для раскрытия образов:

* будет соответствовать нулю или большему количеству символов. Это означает "сюда подходит все, в том числе и ничто". Примеры:

  • /etc/g* соответствует всем файлам в /etc, начинающимся с g или файлу с именем g.
  • /tmp/my*1 соответствует всем файлам в /tmp, которые начинаются с my и заканчиваются 1, включая my1.

? соответствует любому одиночному символу. Примеры:

  • myfile? соответствует любому файлу, имя которого состоит из myfile, за которым следует один символ
  • /tmp/notes?txt будет соответствовать и /tmp/notes.txt, и /tmp/notes_txt, если они существуют

Синтаксис образцов: []

Этот образец похож на ?, но он предоставляет больше конкретности. Чтобы использовать этот образец, поместите любой символ, которому вы хотите найти соответствие внутри []. Получающееся в результате выражение будет соответствовать единичному вхождению любого из этих символов. Вы также можете использовать -, чтобы указать диапазон и даже объединить диапазоны. Например:

  • myfile[12] соответствует myfile1 и myfile2. Образец будет раскрыт, если, по крайней мере, один из этих файлов существует в текущей директории,
  • [Cc]hange[Ll]og будет соответствовать Changelog, ChangeLog, changeLog и changelog. Как вы можете видеть, использование образцов с квадратными скобками может быть полезным для вариаций строчных/заглавных букв.
  • ls /etc/[0-9]* выведет все файлы из /etc, которые начинаются с цифры.
  • ls /tmp/[A-Za-z]* выведет все файлы из /tmp, которые начинаются с заглавных или строчных букв.

Конструкция [!] похожа на конструкцию [], но вместо того, чтобы соответствовать любому символу в квадратных скобках, она соответствует любому символу, если он не попадается между [! и ]. Пример:

  • rm myfile[!9] удалит все файлы с именем myfile плюс одни символ, за исключением myfile9

Предостережения, касающиеся образцов

Вот несколько предостерегающих примеров использования образцов. Так как bash особенным образом рассматривает символы, связанные с образцами (?, [, ] и *), вы должны быть особенно аккуратны при наборе команд, содержащих эти символы. Например, если вы хотите создать файл, который содержит строку [fo]*, следующая команда не может сделать то, что вы хотите:

$ echo [fo]* > /tmp/mynewfile.txt

Если образец [fo]* соответствует каким-либо файлам в вашей текущей рабочей директории, то в /tmp/mynewfile.txt вы найдете имена этих файлов, а не литерал [fo]*, как вы ожидали. Решение? Ну, один подход заключается в том, чтобы окружить ваши символы одиночными кавычками, которые приказывают оболочке bash не раскрывать образцы в кавычках:

$ echo '[fo]*' > /tmp/mynewfile.txt

В таком случае ваш новый файл будет содержать литерал [fo]*, как и ожидалось. Другой подход, вы могли бы использовать экранирование с помощью \ (backslash), чтобы указать bash, что [, ], и * должны трактоваться буквально, а не как образец:

$ echo \[fo\]\* > /tmp/mynewfile.txt

Оба подхода (одинарные кавычки и экранирование с помощью \) имеют одинаковый эффект. Так5 как мы говорим об экранировании с помощью \, самое время упомянуть, что для того, чтобы указать литерал \, мы можете или заключить его в одинарные кавычки, или набрать \\ (это будет раскрыто как \).

Замечание:

Двойные кавычки будут работать аналогично одинарным, но они все же позволяют bash выполнять некоторое ограниченное раскрытие. Следовательно, одинарные кавычки - ваш лучший выбор, если вы в самом деле заинтересованы в передачи команде точного текста. Более подробную информацию о раскрытии образцов можно получить, набрав 'man 7 glob'. Более подробную информацию о кавычках в bash можно получить, набрав 'man bash' и прочитав раздел, озаглавленный ЭКРАНИРОВАНИЕ (QUOTING). Если вы планируете сдавать экзамен LPI, рассмотрите это как домашнее задание :)

Резюме и ресурсы

Резюме

Поздарвления: вы дошли до конца нашего обзора основ Linux! Надеюсь, это помогло вам укрепить ваше знание основ Linux. Темы, с которыми вы познакомились тут, включая основы bash, основные команды Linux, ссылки и образцы, заложили фундамент нашего следующего руководства по основам администрирования, в котором мы охватим такие темы, как регулярные выражения, права доступа, управление учетными записями пользователей и т.д.

By continuing in this tutorial series, you'll soon be ready to attain your LPIC Level 1 Certification from the Linux Professional Institute. Speaking of LPIC certification, if this is something you're interested in, then we recommend that you study the Resources in the next panel, which have been carefully selected to augment the material covered in this tutorial.

Ресурсы

В серии статей "Bash в примерах" Daniel показывает вам, как использовать конструкции программирования bash, чтобы написать свои собственные скрипты. Эта серия (в особенности части 1 и 2) послужат хорошей подготовкой к экзамену LPI уровня 1:


Daniel Robbins

silly photo
This is not really me

Daniel Robbins is the founder of the Gentoo community and creator of the Gentoo Linux operating system. Daniel resides in New Mexico with his wife Mary and two energetic daughters, and is founder and lead of Funtoo. Daniel has also written many technical articles for IBM developerWorks, Intel Developer Services and C/C++ Users Journal.

Chris Houser

Chris Houser has been a UNIX proponent since 1994 when he joined the administration team for the computer science network at Taylor University in Indiana, where he earned his Bachelor's degree in Computer Science and Mathematics. Since then, he has worked on software in a variety of fields including web applications, video editing, UNIX device drivers, and defense, and is currently employed at Sentry Data Systems. He has also contributed to various free software projects such as Gentoo Linux and Clojure. He has most recently co-authored "The Joy of Clojure," available at http://joyofclojure.com.

Aron Griffis

Aron Griffis lives in the Boston area, where he's spent the past decade working for Hewlett-Packard on projects such as Tru64 UNIX network drivers, Linux security certification, Xen and KVM virtualization, and most recently HP's ePrint platform. When he's not actively hacking, Aron mulls over programming problems while riding his bicycle, juggling clubs, or cheering for the Red Sox.