Журнал LinuxFormat - перейти на главную

LXF145:Команды

Материал из Linuxformat
Версия от 18:29, 10 июля 2014; 2sash-kan (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Команды: GNU/Linux и смекалка

Тихон Тарнавский описывает необычные приемы и навыки работы с командной строкой – сравнив их с выкладыванием мозаики.


Идея этой статьи зрела долго – почти пять лет. Ведь написано о командной строке за годы существования Unix не просто много, а невообразимо много; и материалы разнятся как по объему, так и по необходимому для прочтения уровню подготовки и стилю изложения. Исходя из этого, многим может быть непонятно: зачем же браться за ту же тему сызнова? Потому для начала – небольшое объяснение.


Что это, зачем и для кого?

Уникальность предлагаемых заметок в том, что в них я не собираюсь учить вас, уважаемый читатель, работе в командной строке. Вместо того, чтобы сосредоточиться на обучении, я предлагаю вам попытаться понять, чем же так ценна та самая командная строка многим опытным линуксоидам. Да, именно так: понять самим, но с моей помощью. Я не буду вам этого объяснять; объяснить своими словами эти вещи тоже уже пытались многие, но каждый раз на этом пути встает известная проблема понимания: человек, способный уже объяснить любую познаваемую своим опытом истину, говорит на другом языке, чем те, к кому он обращается – именно потому, что они сами этого опыта еще не имеют.

Не будет здесь и методов «от простого к сложному» – вместо этого вам предлагается понять, что ничего сложного здесь нет. Одним словом, попробую отбросить все каноны изложения «основ» и «принципов», а взамен воспроизведу сам процесс. Надеюсь, из этого вы сможете понять, что чувствует человек, имеющий в своих руках столь мощный, гибкий и одновременно простой инструмент. Именно на этом – на ощущении процесса – и предлагаю вам сосредоточиться во время чтения.

Материал будет состоять из практических примеров: иногда совсем небольших, иногда – достаточно объемных. Каждый пример будет снабжен объяснением, но вся суть материала будет в построении этих объяснений. Обычно такие вещи разъясняются «от конструкции»: уже готовый набор команд разбирается последовательно, с пояснением, что же каждый элемент делает. Я же предлагаю пойти противоположным путем: «от задачи». В каждой заметке мы будем ставить перед собой некую задачу, которую человек может захотеть решить, работая в командной строке, и подробно рассматривать ход мыслей этого человека и их практическую реализацию до конечного результата. Именно такой подход, на мой взгляд, и даст почувствовать всю ту красоту средств командной строки, которую, поняв однажды, ни на что уже не захочется променять.

Предназначаются заметки для самого широкого круга читателей, которым будет интересно расширить свои познания в этом вопросе – да и в Linux вообще, поскольку команды, программы и приемы, применяемые при работе в командной строке, составляют основу системы. Если вы только начинаете свое знакомство с Linux, для вас в небольших врезках предусмотрены краткие пояснения даже по самым простым вещам. Если имеете определенный (может быть, даже очень большой) опыт, можете такие объяснения (или некоторые из них) пропускать – целостность остального текста от этого нисколько не проиграет.

Корни

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

  1. «Большой груз легче перенести по частям» Задач, которые человек мог бы захотеть решить с помощью компьютера, великое множество. Поэтому делать по отдельной программе на каждую задачу нерационально – тогда программистом пришлось бы быть каждому. Вместо этого предлагается разбить большую задачу на маленькие кусочки и каждый из таких кусочков решить уже готовым специализированным инструментом. Инструмент этот, ввиду узости применения, достаточно мал и прост для использования его без специальной подготовки. Для объединения этих маленьких деталей в большие конструкции предоставлен достаточно широкий спектр связей. Практика такого разделения задачи будет подробно рассмотрена в каждом конкретном примере.
  2. «Не знаешь (не помнишь) — читай» Все команды и все их параметры в голове удержать не под силу даже тому, кто использует их ежеминутно. Потому не гнушайтесь чтением man-страниц, благо написаны они обычно очень коротко и просто, и на нынешний момент очень многие из них есть на русском языке. Для облегчения усвоения информации и последующего ее поиска (когда забудется) рекомендую (по крайней мере, на первых порах) составлять глоссарий с наиболее часто используемыми командами.


Устраиваемся поудобнее

В Linux много различных командных оболочек; здесь я буду говорить исключительно о bash (Bourne Again Shell), по двум причинам: с одной стороны, она самая распространенная (и используется по умолчанию почти во всех дистрибутивах), с другой – одна из двух самых мощных и гибко настраивамых, а следовательно, и самых удобных (наравне с zsh).

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

“\e[A”: history-search-backward
“\e[B”: history-search-forward

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

В .bashrc рекомендую добавить такую строку:

HISTCONTROL=ignorespace:erasedups

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

На других удобных настройках (касающихся не только истории) я не буду подробно останавливаться; ищите их вместе с уже описанными в файлах .bashrc и .inputrc на диске, приложенном к журналу. Эти файлы нужно положить в домашний каталог, после чего все заданные в них настройки будут доступны для всех новых терминальных окон. А если какие-то из этих настроек окажутся актуальны по ходу повествования, я буду в двух словах пояснять, что они означают.

Для умного автодополнения достаточно установить пакет bash-completion (если такой отдельный пакет есть в вашем дистрибутиве, а не включен в состав пакета bash) и активировать запуск скрипта из этого пакета в том же файле .bashrc.

Рекомендую также обратить внимание на приведенные во врезке сочетания клавиш bash. Например, узнав о наличии специального сочетания, меняющего местами два соседних символа, я не очень понял, зачем оно нужно; но потом обнаружил, что при достаточно быстром наборе перепутанные местами символы – одна из наиболее распространенных опечаток.


Принципы

Вы, думаю, знаете, что традиционный инструментарий Unix (а соответственно, и GNU/Linux) состоит из множества небольших узкоспециализированных утилит. Главное – не подумать, что для работы в командной строке нужно изучать все эти утилиты. Это наименее эффективный подход, хотя, как ни странно, и наиболее распространенный. Напротив, не сосредотачивайтесь на отдельных командах. Поначалу лучше их вообще не стараться специально запоминать, а записывать в глоссарий, о котором я уже писал выше. Смотрите на них как на конструктор или мозаику. Вы в детстве играли с конструктором или мозаикой? Представьте, что во время игры вы бы старательно изучали каждую деталь или каждую фишку. Было бы это интересно или хотя бы результативно? Помогло бы вам такое изучение сложить узор или собрать машину? Утилиты Linux, конечно, немного сложнее по своему устройству, чем мозаичные фишки или детали конструктора – но предназначение у них в большинстве случаев в точности то же: стать частями общей картины или механизма. Поэтому главное, чему и нужно уделить внимание – это связи, взаимодействие между разными командами.

Основных принципов Unix и в целом немного, но нам, по крайней мере на первых порах, будут интересны всего два из них, причем сильно взаимосвязанных. Первый из этой пары: «все есть текст». Именно так: не только информация, которую мы получаем от большинства команд, но и их управляющие параметры, и «данные», которые они обрабатывают – все это обычный текст. И не только это, но и информация о процессах (работающих программах), файлах на вашем диске и правах доступа к ним, «железной» начинке вашего компьютера и подключенных к нему внешних устройствах доступна именно в текстовом виде. Все это сделано именно так сознательно, для удобства обычного человека, делающего свою работу с помощью компьютера.

Второй, смежный, принцип: «если вы не хотите читать вывод программы, заставьте это делать другую программу». Собственно, этот принцип и заключает в себе описанную выше аналогию с конструктором или мозаикой: это те самые «винтики», которыми можно соединить отдельные «детали»; или те «ячейки», в которые вставляются отдельные «фишки».

Но хватит теории: посмотрим, как все это выглядит в реальной жизни. Запускайте терминал – и приступаем.

Работа с файлами: оценка объемов

Давайте начнем с достаточно простой задачи: узнаем, cколько места занимают на диске наши файлы. Понадобиться это может много для чего. Например, вы срочно захотели скачать приложение, и требуется либо найти что-нибудь ненужное и удалить, либо найти что-нибудь нужное, но «не сейчас, а в принципе», и сбросить на какой-нибудь внешний носитель. Естественно будет поиск ненужного начать с самых больших файлов или каталогов. Чтобы узнать, что сколько весит, воспользуемся командой du (du – сокращение от “disk usage”, «использование диска»). Начать можете с вызова ее без параметров; и посмотрите, что получится:

$ du
16 ./.mc
24 ./.ssh
404 ./bin
4 ./.osso-abook/extensions
16 ./.osso-abook/db
24 ./.osso-abook
8 ./.osso/mis
8 ./.osso/menus
12 ./.osso/hildon-input-method
36 ./.osso/hildon-desktop
[…]
51716 ./files/deb
52184 ./files
965120 .

Как видите, вывод не слишком удобен для дальнейшего применения: du прошлась вглубь по всем каталогам и «взвесила» каждый из них. Выискивать среди них самые большие вручную – занятие не легче, чем найти нужные (или ненужные) файлы безо всяких du. Вот здесь и пора применить озвученный принцип: заставить работать вместо нас другую программу. Хорошо было бы отсортировать этот вывод, чтобы самые большие числа шли в конце и мы их сразу легко увидели. Для сортировки существует специальная команда, и называется она весьма очевидно – sort. Так что даже специально искать не нужно. Но по умолчанию она сортирует текстовые строки в алфавитном порядке, а нам нужно отсортировать числа. Поэтому для начала откроем man sort и найдем нужную опцию: -n – сортировать в соответствии с числовыми значениями строк (n от слова numeric; numeric sort – числовая сортировка). Осталось передать полученный выше текст нужной команде для сортировки. Для этого в shell есть специальный «винтик» – конвейер. Обозначается он вертикальной чертой, которая ставится между командами и передает вывод первой на вход второй. Можно было бы сразу попробовать такой конвейер:

du | sort -n

но по выводу команды du вы, думаю, увидели, что результат очень велик. Если он уже будет отсортирован, то хорошо бы оставить только пару десятков последних строк. Как это сделать? Вся мощь конвейеров в том, что мы можем объединять не только две команды, а сколько угодно: ведь вторая, получив от первой некий текст, сделает из него опять-таки текст. А любой другой команде не важно, как этот текст создан – одной командой или двумя; или он вообще лежит в файле или набирается с клавиатуры. Давайте попытаемся найти команду для вывода последних строк. Тут нам снова пригодится команда man: у нее есть специальный ключ для поиска ключевых слов по описаниям man-страниц – -k (keyword – ключевое слово). Узнать о нем можно из руководства к самой этой команде – man man. Используем этот ключ со словом last (последние):

$ man -k last
tail (1) - output the last part of files
(thumbnail)
Рис. 1. Находим самые объёмные каталоги.

Добавим команду tail в конец нашего конвейера (см. рис. 1).

Как видите, по умолчанию мы получили десять строк. Если этого мало, количество строк можно изменить с помощью опции к команде tail, например tail -n 20, или сокращенно tail -20.

Уже достаточно удобно, если нужно искать большие каталоги. А как быть с обычными файлами? У команды du есть ключ -a (all – все, т. е. не только каталоги, но и обычные файлы), но здесь он мало поможет: какие-то каталоги скорее всего будут весить больше и вытеснят файлы из последних строк списка. Например, у меня от добавления этой опции в вышеприведенном конвейере вывод совсем не меняется. Команда du предназначена именно для работы с каталогами, и подсчет «тяжести» обычных файлов – лишь приятный довесок, не более. Как быть? Очевидно, нужно начать с критичной для нас части этой задачи. То есть сначала найти обычные файлы, а потом уже готовый список передать команде du, как только что мы ее вывод передавали командам sort и tail.

Значит, нам нужен поиск по типу файла (здесь важно не путать тип файла с «расширением» – понятием, более свойственным семейству Windows, а не Unix; поскольку в Unix и каталоги, и файлы устройств, и много других сущностей являются файлами, то именно каждое из этих понятий и есть отдельный тип файла). Имя команды поиска столь же очевидное, как и команды сортировки: find (находить). Имя опции для поиска по типу файла не менее очевидно: -type (тип). А значение аргумента, который эта опция принимает, состоит из одной буквы, и для обычного файла эта буква также совершенно ожидаема: f (file).

find -type f

Теперь нужно передать результаты поиска команде du. Сделать это напрямую по конвейеру на этот раз не получится, т. к. du принимает список файлов из командной строки, а не со стандартного ввода. Но именно на этот случай в комплекте с find (в том же самом пакете findutils) есть не менее богатая возможностями программа xargs, которой в простейшем варианте нужно передать только имя команды (и опции, если они нужны), и она сама подставит свой стандартный ввод в командную строку:

find -type f | xargs du

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

find -type f | xargs du | sort -n | tail
(thumbnail)
Рис. 2. Находим самые увесистые файлы.

Все уже будет как задумано – но только если у вас нет файлов с пробелами в именах. Иначе каждый такой пробел будет воспринят командой xargs как разделитель аргументов командной строки, и вместо размера файла вы получите столько сообщений о ненайденных файлах, на сколько «слов» пробелами разбивается имя. Но не переживайте, это тоже предусмотрено авторами findutils: велите команде find использовать в качестве разделителя имен «нулевой» символ, а команде xargs – что вывод нужно делить на отдельные имена только «нулевыми» символами (см. рис. 2). Теперь найти большие файлы или каталоги легко.

Если вы предполагаете, что какие-то команды могут быть нужны вам достаточно часто, то было бы удобнее их сократить при вводе. Например, для только что созданных нами конвейеров можете добавить вваш .bashrc такие строки:

alias bigdirs='du | sort -n | tail -20'
alias bigfiles='find -type f -print0 | xargs -0 du | sort -n | tail -20'

Хотя, чтобы чувствовать себя свободнее в добавлении таких сокращений и в то же время не засорять стартовый файл bash, в который может быть нужно добавить другие удобные настройки, предлагаю вынести подобные вещи в отдельный файл (например, .bash_aliases), а из .bashrc его вызывать. Заодно можно будет легко применять новые добавления в этом файле:

. ~/.bash_aliases

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

Работа с системой: оценка ресурсов

Представим другой критический случай: система вдруг начала «тормозить». Знакомо? Происходить это может по двум причинам: либо какой-то процесс (работающая программа) слишком сильно нагрузил процессор, либо стал использовать очень много памяти. Обе эти ситуации (да и многое другое, что касается процессов) можно отследить с помощью команды ps (processes snapshot, снимок процессов). Здесь нам достаточно знать, что наиболее полную информацию о процессах можно получить командой ps aux. Дальше, думаю, понятно: мы снова должны отсортировать и взять последние строки. Только как сортировать? Давайте посмотрим на заголовки столбцов, которые выводятся в первойстроке:

$ ps aux | head -1
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

То есть, чтобы отыскать самых прожорливых поглотителей процессора, нам необходимо отсортировать список процессов по третьему столбцу. Понятно, что тут должна помочь команда sort. Применим ключ -k (keyfield, ключевое поле) и числовую сортировку:

ps aux | sort -nk 3
(thumbnail)
Рис. 3. Процессы, активно использующие процессор.
(thumbnail)
Рис. 4. Процессы, занимающие много памяти.

Скорее всего нам будет достаточно двух-трех самых жадных процессов. Добавляем tail -3 и безошибочно находим виновника – pidgin (см. рис. 3).

Самый общеизвестный и безжалостный способ решения такой проблемы – избавиться от найденного виновника раз и навсегда командой killall pidgin (или даже killall -KILL pidgin, если не послушается). Но если мы в курсе, что программа занята чем-то нужным, а нам просто понадобилось что-то заархивировать, можно мешающий процесс приостановить, а затем продолжить:

$ killall -STOP pidgin
$ tar cf archive.tar.lzma --lzma dir/
$ killall -CONT pidgin

Теперь понятно, что для выяснения ситуации с памятью можно поступить аналогично (только «хвост» оставим чуть подлиннее). Но возьмем не четвертое поле, а шестое: в нем отображается тот же объем, но не в процентах, а в килобайтах, т. е. немного точнее (см. рис. 4).

Персональные инструменты
купить
подписаться
Яндекс.Метрика