Также очень удобно использовать
grep совместно с
find. Например: найти все файлы, если в имени файла или каталога есть слово Distrib
Или можно использовать grep для поиска по содержимому:
$ find /etc -print0 | xargs -0 grep ext3
найдёт все файлы в каталоге /etc, содержащие слово ext3 и выведет строки с этим словом. Если использовать ключ -l у grep, то выведены будут только имена файлов, в которых встречается искомая строка. Таким образом можно использовать grep как еще одно условие в команде fnid.
Команда grep также может искать по шаблону, но её шаблоны отличаются от шаблонов shell. В grep символ "*" означает повторение предыдущего символа любое число раз (включая 0), "+" - также, но от 1 раза. Например "n+" эквавалентно "nn*". "." означает любой символ. Таким образом то, что в shell было "*" в grep будет ".*", а вместо "?" будет ".". Если необходимо ставить просто точку, то, как всегда, перед ней ставится обратный слэш "\". Кроме того есть ещё два специальных символа "^" - начало строки и "$" - конец строки. Таким образом маска shell "*.bak" в grep будет выглядеть как "^*.bak$". Шаблоны grep называются регулярными выражениями.
sed: обработка строк
В самом примитивном случае grep тоже обрабатывает строки: либо выводит строку, либо нет. Но часто необходимо выведенную строку привести к удобному виду. В приведенном выше примере с командой mount, предположим, что нам нужны только точки монтирования. Разумеется, если просмотр делает человек, то он и так увидит всё что ему надо, но, предположим, что результат нам нужно положить в параметры какого-нибудь скрипта. Если попытаться описать человеческим языком, что нужно сделать, чтоб из строки "/dev/hda3 on / type ext3 (rw,noatime)" получить только точку монтирования, то получиться что-то вроде:
удалить всё, что, до символов "on "
удалить всё, что, после символов " type"
Соответственно команда выглядеть будет так:
$ mount | grep ext3 | sed 's/.*on //' | sed 's/ type.*//'
Команда s// у sed имеет формат s/шаблон/строка/ и заменяет то, что попадает под шаблон на строку. В приведенном примере она просто удаляет найденное регулярное выражение. Если шаблон встречается в строке несколько раз и надо заменить все экземпляры, то в команде s// добавьте букву g в конец. Рекомендуется команды sed брать в одинарные кавычки (апострофы), чтобы shell не пытался интерпретировать символы.
awk: работаем с таблицами
Разумеется речь в этом подразделе пойдет о текстовых таблицах. Например, такую таблицу выдают команды "ls -l", mount и многие другие. Можно считать, что строки состоят из нескольких полей, разделенных пробельными символами (последовательностью пробелов и табов). Тогда в строке "/dev/hda3 on / type ext3 (rw,noatime)" точку монтирования можно считать третьим полем. И вот окончательное решение: третьим полем. И вот окончательное решение:
$ mount | grep ext3 | awk '{print $3}'
Общий формат команды для
awk выглядит как "условие {действие}", причем поля соответсвующей строки заносятся в нужные переменные. Условие может быть пустым (как в вышеуказанном примере), может быть регулярным выражением. Абсолютно эквивалентный вариант предыдущей команды:
$ mount | awk '/ext3/{print $3}'
И условие может быть практически любым условием с переменной поля. Например в нашем примере можно заметить, что ext3 должно быть именно в 5-ом поле (иначе будут показываться, например, также точки монтирования со с названиями типа text3, так как ext3 ищется во всей строке). Так вот, чтобы получить именно то, что надо, выполните команду
$ mount | awk '$5=="ext3"{print $3}'
awk также может работать с полями, разделёнными не пробельными символами, а любыми другими. Для этого у него есть параметр -F. Например, чтобы вывести все имена (первое поле) из /etc/passwd (поля разделены двоеточиями), нужно выполнить команду
$ awk -F : '{print $1}' /etc/passwd
Сортировка строк
Часто бывает нужно не только вывести в нужном формате, но и отсортировать по нужным полям. В той же команде mount можно сортировать по точке подключения или по имени устройства. Эту функциональность обеспечивает команда sort. В простейшем варианте она сортирует всё, что ей приходит на стандартный вход как строки и выводит на стандартный вывод. Для сортировки по какому либо полю используется параметр -k затем пишутся через запятую начальное и конечное поля, по которым нужно сортировать. Этот ключ можно использовать несколько раз. Если надо изменить изменить разделитель поля, то используйте ключ -t. Для численной (а не строковой) сортировки используется ключ -n. Например, если надо вывести файл /etc/passwd (разделитель
отсортированным по номерам пользователей (3-е поле), то нужно ввести команду:
$ sort -n -t : -k 3,3 < /etc/passwd
Еще полезной команда sort оказывается при использовании du для выяснения куда уходит больше всего места.
позволит вывести список файлов и каталогов с размерами отсортированный по размеру. Ключ -h у du использовать нельзя, иначе не удастся сортировка.
В некоторых случаях кроме сортировки нужно убрать повторяющиеся строки. Для этого используется команда uniq. Она так же, как и sort берет строки со стандартного ввода, а результат выдает на стандартный вывод. Для удаления дубликатов строки должны быть предварительно отсортированы.
head и tail: быстрый обзор файла
Как уже было замечено, для просмотра файла есть команда cat, но она очень неудобная, если нужно просмотреть большой файл, например те же системные журналы, длина которых может достигать нескольких тысяч строк. Если нужно взглянуть только на начало файла (например, там часто бывает информация о том, что в нем находится) есть команда
head.
$ cat /etc/passwd | head
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
adm:x:3:4:adm:/var/adm:/bin/false
lp:x:4:7:lp:/var/spool/lpd:/bin/false
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/bin/false
news:x:9:13:news:/usr/lib/news:/bin/false
По умолчанию head выводит первые десять строк, если надо больше или меньше задайте ключ вида -n количество_строк. Например, head -n 5 выведет 5 строк. Обычно head используют совместно с sort, например, чтобы вывести 10 самых больших каталога (упражнение).
Аналогично команда tail выводит последние строки. Особенно полезна она для просмотра журналов системных событий. Также можно с её помощью смотреть за системными событиями в реальном времени. Например
# tail -f /var/log/messages
будет показывать новые записи в файле /var/log/message по мере их появления. Прервать выполнение этой команды можно как обычно, нажав ^C.
Кроме просмотра эту команду можно использовать, чтобы вести журнал событий в двух местах, например
# nohup tail -f /var/log/messages > /my/copy &
позволит всегда иметь копию системного журнала, даже если файл /var/log/messages будет испорчен (по вине аппаратуры или злоумышленника). Но учтите, что таким образом можно получить копию только тех данных, которые дописаны в конец, поэтому не следует пытаться таким образом получить копию, например, базы данных.
[b]less: просмотр текстовых файлов[/b]
И всё таки, что делать, если необходимо просмотреть весь файл, а не его первые или последние строки и файл очень большой. Для этого в Linux есть программа просмотра текста под названием less. Если Вы хоть раз уже использовали команду man (см. man), то Вы с ней уже сталкивались. Дело в том, что man его использует для отображения документации. Для того, чтобы посмотреть произвольный файл, можете просто набрать "less имя_файла". Кроме того, можно просматривать сразу резултат вывода команды. Например,
вывода. При просмотре используются обычные клавиши со стрелками, PgUp, PgDown. Кроме того, если Вы, например, хотите использовать less при доступе через telnet (он позволяет использовать только алфавитно-цифровые клавиши), то двигаться по тексту можно вводя следующие латинские символы:
j - вниз
k - вверх
f - PgDown
b - PgUp
Помощь по всем доступным символам доступна при нажатии кнопки "h". Также перед командами j и k можно вводить произвольное число и тогда передвижение будет происходить на соответствующее количество строк. Например, чтобы передвинуться на 30 строк вниз надо набрать "30j". Кроме того есть возможность перейти на определенную строку: "30g" или "30G" перейдут на строку 30. Без параметра g переходит на начало, а G на конец файла. Команда "=" показывает, где сейчас находимся (строки и байты).
Из полезных команд хотелось бы упомянуть две. Команда "/" позволяет найти строку в файле и перейти на неё. Например, по команде "/find" less переходит на ближайшее слово "find" в открытом файле. Если "/" используется без параметра, то происходит поиск того, что только что искалось (как правило используется, чтоб найти следующее такое же слово). Вторая полезная команда: F. Она переводит less в режим аналогичный tail -f. Прервать этот режим можно командой ^C. Любую команду less можно передать через параметр "+". Например
# less +F /var/log/messages
позволит также следить за журналов, но при помощи less.
vi: редактор текста
Благодаря вышеупомянутым командам обработки текста Вы теперь можете делать простое редактирование файлов, например, добавить в конец файла строку или изменить какую-нибудь настройку по её имени. Просмотр текста любого объема достаточно удобно выполняется при помощи less. Но часто требуется провести достаточно сложное редактирование текста. Для этого в UNIX есть редактор vi. В Linux используется его вариация под названием vim (Vi IMproved). Запуск производится очевидным образом
или
Основным принципом vi является наличие двух режимов работы: командный режим и режим ввода текста. В режиме ввода любая нажатая клавиша непосредственно вводится в текст, а в командном режиме они воспринимаются как команды. Если Вы находитесь в режиме ввода, то перейти в командный режим можно нажав кнопку Esc. Введенный символ как правило можно отменить, нажав Backspace. Кроме этого в vim (но не в vi) в режиме редактирования работают клавиши перемещения по тексту и кнопка Del. В командном режиме, очевидно, самая важная команда: перейти в режим ввода. Для этого нажмите или "i"(от слова insert) или "a"(от слова append). Соответственно ввод начнется или перед символом, на котором был курсор или после этого символа.
Стрелки могут не работать даже в командном режиме (например, при входе по telnet). Тогда перемещаться можно почти как в less:
j - вниз
k - вверх
h - влево
l - вправо
Клавиши выбраны так, чтобы находиться под рукой при десятипальцевом методе печати.
Перед любой командой так же как и в less можно вводить число, тогда команда будет выполнена нужное число раз. Например введя "80i*" Вы получите строку из 80 звездочек. Отменить последнее действие можно командой u (в vim можно отменять сколько угодно раз). Вновь вернуть командой ^R. Сохранить и выйти можно нажав дважды Z (обязательно большую).
Нажав ":" можно перейти в режим многосимвольных команд. Например в этом режиме можно вводить команды вида s/aa/bb как в sed. По-умолчанию эта команда действует только на текущую строку. Если надо применить замену к нескольким строкам, то надо вводить ,s/aa/bb где - номер первой строки, где нужно провести замену, а - номер последней строки. Последняя строка файла обозначается символом $, текущая строка - ".", также можно задавать относительные номера строк. Например, +5 значит на 5 строк вперед от текущей строки, аналогично -5 - 5 строк назад. Команда :help позволяет получить помощь по vim (очень подробную, включающую в себя учебник). :q! позволяет выйти без сохранения.
Также есть клавиши быстрого перемещения по тексту:
\ - начало строки
$ - конец строки
w - слово вперед
b - слово назад
% - перейти на парную скобку (очень полезно при редактировании программ)
Напоследок хотелось бы заметить, что несмотря на сложность в изучении работа с vim очень удобна, потому что человек мыслит объектами, а vi/vim позволяет редактировать в тех командах, которыми человек думает: "удалить следующие два слова, перейти на 5 строк вниз, заменить Иван, на Петр", кроме того, команды расположены удобно при десятипальцевом методе печати. Также в vim есть подсветка синтаксиса, автоматическая расстановка отступов в программах, переход по функциям в C/C++/Java и многое другое.
Есть лишь один редактор, который превосходит его по гибкости. Он называется emacs. Разумеется в Linux он также доступен, но не всегда есть в минимальной установке (в отличие от vim).
Управление задачамиUNIX является многозадачной системой. Это позволяет выполнять команды и при этом одновременно продолжать работать или напротив, дать команду на сервере посредством дистанционного доступа, затем отключиться и вернувшись увидеть результат выполнения команды.
Для выполнения команды в фоновом режиме после неё надо написать знак &. Например, если надо найти все файлы *.html на диске, то процесс это долгий и, чтобы команда работа и не мешала можно её выполнить так:
$ find / -name '*.html' > result 2>&1 &
Перенаправление вывода делать практически обязательно, если Вы не хотите, чтобы программа писала результат на экран, мешая работать. На экран вывелся номер задачи в квадратных скобках и номер процесса. После этого, если ввести команду
то получим список запущенных работ. Если работа завершена, то вместо Running будет Done, а при повторном запуске команды jobs её в списке уже не будет.
Если надо завершить фоновую задачу, то можно воспользоваться командой
kill После знака % должен быть номер задачи, какой он был в команде jobs. После остановки задачи будет выведено сообщение (обычно достаточно нажать ещё раз Enter)
Для того, чтобы процесс не прерывался после выхода из терминала начинайте его с команды nohup
$ nohup find / -name '*.html' > result 2>&1 &
В этом случае Вы сможете вновь войти в систему позже и посмотреть резултаты.
Если Вы уже запустили длительную команду и хотите её приостановить, нажмите ^Z. Тогда команда приостановится и Вы получите доступ к командной строки. Для продолжения выполнения команды в обычном режиме наберите
Или можете перевести её в фоновый режим:
Если надо посмотреть процессы не принадлежащие к текущему терминалу (например, созданные указанным выше образом), то можно воспользоваться командой ps. Без параметров она показывает только процессы принадлежащие текущему терминалу
$ ps
PID TTY TIME CMD
9329 pts/0 00:00:00 bash
9964 pts/0 00:00:00 find
9965 pts/0 00:00:00 ps
В первой колонке номер процесса, его так называемый PID, в последней - имя команды, которая запущена в этом процессе. Если нужно полное имя команды, то нужно добавить несколько параметров
$ ps -o pid,args
PID COMMAND
9329 -bash
10030 find / -name *.html
10069 ps -o pid,args
Ключ -o позволяет изменять формат вывода. Для вывода всех процессов, добавьте ключ -e, а если хотите получить только свои процессы выполните команду
Ключ -u позволяет фильтровать вывод по пользователю, а переменная USER хранит имя текущего пользователя.
Для того, чтобы остановить процесс, полученный таким образом, пользуйтесь той же командой kill, но в качестве параметра подставляйте номер процесса (без символа %).
Если процесс завис, то он может не отвечать на сигнал kill. Тогда можно сделать принудительное прерывание процесса той же командой kill, но с параметром -KILL.
Но запомните, что команда kill с ключом -KILL не позволяет приложению завершиться корректно и может привести к потере данных. Если программа не завершилась после такой команды, значит зависание произошло в одной из функций ядра. Тут уже ничем не поможешь, разве что можно отправить сообщение об ошибке (bugreport) разработчикам ядра.
Ещё раз про подход UNIX
Как Вы, очевидно, уже заметили, в UNIX для решения любой задачи есть несколько путей. Например для обработки файлов можно использовать как параметр -exec, так и xargs. Функциональность awk и grep также перекрывается (awk шире, но медленнее и сложнее). Общий принцип этого подхода: у каждой задачи должен быть свой наиболее подходящий инструмент. Разнообразие этих инструментов в Linux ещё больше: perl, python, tcl, не считая огромного количества специализированных утилит. Рекомендую постараться если не изучить их все, то хотя бы выяснить для каких задач что лучше всего подходит и изучать по мере необходимости.
Второй принцип UNIX: команда не должна запрашивать подтверждения и не должна ничего сообщать при успехе, но обязательно должна сообщать об ошибке. В некоторых случаях этот принцип кажется не к месту, например, в командах типа rm или форматирования диска. Именно поэтому надо всегда помнить о таком "недружелюбном" поведении системы.
Третий принцип: любая задача разбивается на маленькие кусочки, затем для каждого кусочка пишется максимально общая программа (пример: задача - фильтрация строк и grep, умеющий обрабатывать произвольные регулярные выражения). Затем всё это склеивается при помощи shell (конвейеры, подстановка аргументов, временные файлы, и т.д.). Побочным эффектом данного подхода является то, что практически все компоненты UNIX являются заменимыми. Например, Linux является по сути UNIX, но с другим ядром (полностью совместимым). Аналогично, grep в Linux написан группой программистов GNU, но это не мешает использовать те же скрипты, что и на других UNIX системах или даже поставить GNU grep на любой другой UNIX.