- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF141:Shell
Материал из Linuxformat.
- Командная строка Меньше путаться с командами и работать на 110% эффективнее
Содержание |
Терминал: Мощь инструментов
- Если вам претит порочить свою репутацию связями с графическим интерфейсом, ускорьте путь к нирване при содействии Боба Мосса.
К тем, кто отважится заявить, что работает в Linux, сразу применяется стереотип: все думают, что они, забившись в угол родительского дома, коротают время за набором непонятных символов на черном экране, с целью перезагрузить Матрицу или взломать защиту Пентагона. Но в реальности люди уже давно забыли эпоху командной строки, привыкли к панелям инструментов, иконкам и мыши и вынуждены считаться с узколобостью графического интерфейса.
На данном уроке мы вернемся к тому, для чего и затевались компьютеры – возьмем все возможное от аппаратной части, узнаем, как все это на самом деле работает, и решим некоторые задачи. Если все, что вы умеете – пользоваться командой cd и копировать и вставлять код с форума, добро пожаловать: эта статья – для вас.
Пока вам достаточно будет начать с простейшего: определить переменную в командной строке. Это особенно удобно при работе с одним и тем же файлом, если вам неохота каждый раз набирать полный путь к нему в командной строке. К счастью, это довольно просто:
var=1 var2=false var3=“/home/$user/file.txt”
Все эти объявления переменных корректны, и тип переменной задавать не нужно: он определяется автоматически. Чтобы воспользоваться переменной в командной строке, просто добавьте перед ее именем знак доллара. Аналогично можно использовать так называемые «алиасы» для часто используемых команд.
alias la=‘ls -a’ alias pa=‘ps -a’
Недостаток обоих этих методов в том, что переменные существуют только в пределах одного сеанса терминала. Чтобы они прожили подольше, добавьте их в ~/.bash_aliases, а переменные можно сохранить в ~/.bashrc.
Если вам нужен оператор условия, вы будете рады услышать, что для задания способа получения результата можно использовать выражения if-else. Вот пример:
if uname -a | grep “GNU/Linux” > /dev/null; then echo “У вас работает Linux”;fi
Эта команда направляет полученную системную информацию команде grep (чтобы узнать о ней подробнее, см. врезку) и отправляет ее результат в /dev/null, так что на экран ничего не выводится. Оператор условия if определяет, возвращен ли результат от grep, и если да, выводит строку «У вас работает Linux» в окно терминала. Теперь можно расширить эту команду, добавив выражение else как в приведенном ниже примере:
if uname -a | grep “GNU/Linux” > /dev/null; then echo “Вы хороший человек”; else echo “Ричард Столлмен вас не полюбит”; fi
Операторы if можно также вкладывать в выражения else, по той же схеме.
Зациклим цикл
Вы можете спросить: зачем вообще нужны циклы в командной строке? Ну, допустим, чтобы скопировать строго определенные файлы из одного места в другое на основе критерия, который содержится в переменной, постоянно обновляемой другим процессом. Впрочем, более вероятно бывает, что требуется распаковать большое количество tar-архивов. Для этого пригодятся циклы for или while. Воспользуемся первым вариантом, так как нам необходимо выполнить все итерации и перейти к другим действиям, а не сидеть и ждать события, которое нас остановит:
for i in *.tar.gz; do tar xfs “$i”; done
Самая хитрая часть этой команды – маска для поиска всех файлов с расширением tar.gz. Затем для каждого соответствующего i распаковывается содержимое архива. Цикл заканчивается после обработки всех файлов, предоставленных командой ls.
Кстати, цикл можно контролировать переменной, изменяемой в другом терминале (например, надо сделать что-то сразу по завершении сборки). Запустите в одном терминале такую команду:
while(checkVar); do sleep 1; echo “ждем…”; done
Она будет ожидать, пока значение переменной checkVar не изменится на false, а до тех пор будет раз в секунду выводить в окно терминала сообщение “ждем…”. Если вам когда-нибудь понадобиться ввести команду длиной более одной строки, просто наберите \ и нажмите Enter. Слева появится символ >, и вы сможете набирать команду дальше.
Теперь, научившись работать с файлами, пора начать считывать из них и записывать в них данные. Одна из самых важных команд в вашем арсенале – less. В Интернете имеются руководства, советующие использовать ее так:
cat ~/myFile.txt | less
Не верьте им! Того же самого (при этом по-прежнему можно будет прокручивать файл клавишами управления курсором) можно добиться командой
less ~/myFile.txt
Меньшее — это большее
У less на диво много параметров, способных вам пригодиться. Например, если у вас ошибки в каких-то строках, передайте команде параметр -N, и она покажет номера строк. Если вам нужна дополнительная информация (имя файла, смещение от начала файла в процентах и т. д.), воспользуйтесь вместо него ключом -M.
Кроме того, с помощью less можно открывать более одного файла, таким образом:
less file1.txt file2.txt
С помощью :n и :p («следующий» и «предыдущий», соответственно) можно переключаться между двумя файлами. Если необходимо открыть еще один файл, не закрывая два уже открытых, наберите :e и имя файла. Чтобы закрыть текущий файл, наберите :d.
Однако самая интересная возможность less – это восклицательный знак !. Наберите его вместе с командой, и less исчезнет; будет запущена команда, а затем less появится снова. Это удобно для решения нескольких задач одновременно, но еще удобнее, если использовать % для ссылки на текущий файл. Таким образом, достаточно набрать
!ls $home >> %
и результат выполнения команды ls добавится прямо в файл, который вы просматриваете. При возвращении в less буфер обновится, и вы сможете продолжать работу как обычно.
Когда-нибудь простого просмотра текстовых файлов станет недостаточно, и вы столкнетесь с необходимостью сравнить содержимое двух файлов на наличие изменений. Это особенно удобно для разработчиков ПО, у которых есть несколько рабочих копий исходного кода, но может пригодиться и при работе с резервными копиями. Если вы хотите просто вывести различия в окно терминала, выполните эту команду:
diff file1.txt file2.txt
Это само по себе интересно, но не слишком полезно. А если мы захотим применить различия между двумя файлами к file1? Мы запишем их в файл, а затем «залатаем» (patch) файл с помощью следующих команд:
diff -u file1.txt file2.txt >> changes.diff patch changes.diff
Ключ -u гарантирует, что различия выводятся в стандартном формате diff, а если текстовые файлы находятся в подкаталогах текущего каталога, добавьте к команде patch ключ -R.
В поиске
Последняя важная утилита, после освоения которой, вы, вероятно, превратитесь из новичка в мастера – команда find.
Первое, что нужно уяснить – команда отнюдь не очевидна. Не воображайте, что набрав ‘find this’ или ‘find that’, вы увидите результат. К сожалению, у разработчиков были другие планы, и они намеренно усложнили команду, для гарантии, чтоб вы прочли документацию, над которой они корпели, пренебрегая личной жизнью… вероятно. Как бы то ни было, кривая ее обучения крутая, и мы преодолеем ее за несколько шагов.
Вот простейший из вариантов команды find, который может вам встретиться
find .
Впечатляет? Эта маленькая команда выводит список всех файлов в вашем домашнем каталоге. Но мы явно хотим большего: например, найти файлы с определенным именем. Для этого воспользуемся командой
find . -name=“* a”
Эта команда находит все файлы в текущем каталоге, имена которых содержат ‘a’. Можно искать файлы и по размеру, используя -size +10k для файлов, размер которых больше 10 КБ, или -size -10M для файлов, размер которых меньше 10 МБ. Для поиска файлов определенного владельца воспользуйтесь параметром -user, например, -user bob, а для поиска результатов, не соответствующих критерию – параметром -not. Теперь добавим все это в приведенную ранее команду:
find . -name=”* tex” -size +1M -user bob find . -not -name=”* tex” -size +1M -not -user bob
Первая команда находит все файлы, в имени которых содержится tex, с размером больше 1 МБ и владельцем bob. Вторая команда (благодаря умело расставленным not) найдет все файлы, в имени которых не содержится tex, с размером больше 1 МБ и владельцем которых не является пользователь bob. Можно поставить даже двойное отрицание (-not -not), но, понятное дело, разве что для собственного развлечения.
И, наконец, параметр -newer, благодаря которому мы найдем файлы, более новые по сравнению с заданным. Эта возможность особенно пригодится системным администраторам (или любопытной Варваре), желающим узнать, что за файлы пользователь создал в неком каталоге. Для этого скомандуйте
find . -newer /path/to/file
Найти старые команды
Мы кратко упомянули о том, что с помощью клавиши Tab можно автоматически дополнять команды, а «стрелкой вверх» просматривать предыдущие команды, но наблюдательные пользователи заметят, что если продолжать нажимать «стрелку вверх», можно увидеть все команды, набранные вчера, позавчера и на всей прошлой неделе: Bash сохраняет все команды, которые вы назапускали в прошлом, и с этой дополнительной возможностью вы станете ниндзя командной строки.
Чтобы найти команду, выполненную ранее, воспользуйтесь символом !. Просто наберите его после нескольких символов искомой команды. Например, команду:
Если вы заметите, что выполняете одни и те же команды снова и снова, или вам необходимо назначить выполнение задачи на определенное время, подумайте о написании скрипта и, возможно, о его запуске по расписанию с помощью crontab. К сожалению, на этих четырех страницах не уместить рассказ о том, как писать скрипты оболочки, но в LXF136 есть руководство по данной теме.
mkdir /etc/init.d/random_folder
можно вызвать снова с помощью
!mk
Область поиска можно расширить, не ограничивая ее только началом команды, с помощью символов !?, и вызвать предыдущую команду таким образом:
!?dom
Как видите, здесь для запуска последней команды мы употребили “dom” из “random”.
Хотя этот прием удобен, его не следует применять с разрушительными командами вроде rm, так как команда не только находится, но и немедленно выполняется, и если вы совершите роковую ошибку, остановить оболочку не удастся!
Однако мы не всегда можем предвидеть, что произойдет при выполнении команд с помощью этих маленьких трюков. Для этого нужно углубиться в историю команд Bash. Для начала нажмите Ctrl+R – это переведет Bash в режим поиска по истории команд. По мере набора команды будут появляться вероятные варианты, пока не возникнет команда, которая вам нужна. Когда это произойдет, либо нажмите Enter и немедленно выполните команду, либо нажмите Esc, чтобы выбрать команду из истории и продолжить ее редактирование. Это особенно удобно, если вы потратили несколько часов на исправление ошибки, вызванной некоторой командой, и теперь хотите создать правильную версию этой команды…
Метод перебора
Если вы точно не знаете, какая команда вам нужна, но ощущаете дежа-вю по поводу проблемы, которую вы пытаетесь решить, вытяните всю историю команд и затем выполните конкретную команду оттуда. Сначала выведем все команды в памяти с их ID-номерами с помощью следующей команды:
history | grep -i “кусок_команды”
Здесь кусок_команды – критерий поиска. Найдя нужную команду, просто наберите
!n
где n – номер команды в истории.
И последнее замечание. По выполнении выбранной команды она становится вашей последней командой, а значит, последней командой в истории Bash. Это стоит помнить, так как попытка выполнить одну и ту же команду из предыстории может привести к очень странным результатам, потому что связанное с ней содержимое будет меняться с каждым запуском!
Многозадачность
Команда watch поможет избежать повторного набора команд. Например, команда watch ls -A будет запускать ls -A раз в две секунды и отображать результат в окне терминала.
Когда вы переключите свою оболочку в режим полного экрана, вам может показаться, что вы вернулись во времена Тэтчеризма и «Смитс», потому что с виду можно работать только с одной задачей в один момент времени.
Вы будете рады узнать, что на самом деле это не так. Как и в большинстве версий Unix, комбинация клавиш Ctrl+Alt+F1...F6 проведет вас по виртуальным терминалам и графической среде. Это означает, что в один момент времени можно выполнять несколько задач и в случае зависимости одной команды от результата другой пользоваться командой watch, описанной далее в этой статье.
Причина, по которой ваш рабочий стол (например) находится в одном из этих виртуальных терминалов – в том, что X-сервер выполняется в одном из них, а если бы многозадачность не поддерживалась, вы бы смогли запустить только рабочий стол и ничего больше!
Графический терминал – не оксюморон
Хотя никому не запрещено просто развернуть оболочку на весь экран, выйдя вон из графического терминала, вы обнаружите, что и графические терминалы обладают кучей функций, делающих работу продуктивнее.
Например, нажатие Tab после набора нескольких букв имени файла или команды завершит строку, которую в противном случае пришлось бы набирать полностью. А с помощью клавиши «стрелка вверх» можно перемещаться по предыдущим командам, не набирая их снова.
Если вы пользуетесь Konsole, можно настроить установку на слежение за активностью других терминалов (например, ожидать завершения долгой задачи сборки) с помощью команды watch. И, конечно, можно открыть несколько вкладок с виртуальными терминалами, вместо того чтобы постоянно переключаться из графического окружения в текстовые экраны.
Grep – это Бог
Grep – мощнейшая команда поиска, хотя большинство пользователей Linux не пользуются ею регулярно. Обычно команды, которые вам, возможно, уже попадались, включают нечто подобное такой простейшей команде grep:
grep “dogs” *
У этой команды – прорва параметров, большинство из которых знать не обязательно. Однако некоторые могут вам пригодиться в повседневной работе с командой:
- -c Посчитать число соответствий в файле.
- -i Сделать поиск нечувствительным к регистру.
- -l Вывести имена файлов с соответствиями.
- -n Вывести номер строки соответствия.
- -r Рекурсивно обрабатывать подкаталоги.
- -v Показать содержимое, не соответствующее критерию поиска.
Например, если нужны рекурсивный поиск по каталогам для указанного критерия, нечувствительный к регистру, и вывод результатов, не соответствующих критерию, воспользуйтесь командой
grep -ilrv “dogs” *
Команды grep можно соединять через канал; запустим приведенную выше команду снова, но изменим ее так, чтобы включались только файлы, соответствующие критерию. Однако исключим все файлы с расширением .log:
grep -ilr “dogs” * | grep -cv “\.log$”
Обратите внимание на обратный слэш в параметре второй команды: он необходим для экранирования точки и знака доллара, чтобы они не интерпретировались как символы маски и обрабатывались бы только файлы, заканчивающиеся расширением .log. Впрочем, File.log.bin не подойдет. В конце команды рекомендуется приставить параметр -color, подкрасив результат, чтобы он выделялся на фоне большого объема вывода; да и для глаз это приятнее, чем монохром.
Советы профессионала
Если вы освоились в командной строке и уже хотите прыгать через несколько шагов, то будете рады узнать, что можно произвести кое-какие сокращения. Например, в системах, применяющих sudo, можно, набрав команду, нарваться на сообщение «x требует прав доступа root» вместо желаемого результата. Чтобы не перенабирать всю строку или использовать клавиши up+home и дописывать sudo, воспользуйтесь взамен следующей командой, которая повторит предыдущую команду с правами доступа root:
sudo !!
Также имеется сочетание клавиш «Мета» + «.». Мета-клавиша в Bash – Esc (хотя иногда она помещается справа от клавиши пробела), и по нажатию этой комбинации клавиш последний аргумент предыдущей команды вставится в конец набираемой строки. Это особенно удобно, например, если вы переместили текстовый файл в каталог и потом захотели добавить туда текст. Нажатие этой комбинации сразу после набора команды
echo “appended text” >>
скопирует файл назначения в конец вашей команды.
Управляем процессами
Наискорейший способ найти «пожирателей ресурсов» в вашей системе – набрать top в окне терминала и нажать Enter. Это одна из первых команд, которая рассматривается в руководствах по командной строке Unix; она предоставляет большой объем информации, но с помощью определенных сочетаний клавиш можно отсеять лишнее и просмотреть важную информацию.
Самые важные столбцы: PID (идентификатор процесса); USER (пользователь, от имени которого выполняется процесс); NI (значение параметра nice), управляющее тем, как легко процесс разделяет ресурсы; и команда, с которой он связан. Все столбцы, помеченные звездочкой, не обязательны – просто нажмите на клавиатуре клавишу с буквой, которую вы видите слева от строки, и соответствующий столбец будет показан или скрыт.
Нажав Shift+F, вы сможете выбрать столбец, по которому сортировать данные. Рядом с каждым столбцом есть буквы – просто нажмите соответствующую клавишу. Теперь, видя все данные, можете нажать K и добавить идентификатор процесса, чтобы убить конкретный процесс. Это гораздо проще, чем набирать kill 0100 полностью (здесь ‘0100’' – идентификатор процесса, который вы хотите убить), так как придется либо закрывать top, либо запускать команду в другом виртуальном терминале. Если вы хотите повысить приоритет процесса, нажмите R (re-nice) и введите идентификатор процесса точно так же, как с K; но в этом случае вы увидите, как снизится значение параметра nice, показав, что вероятность отобрать используемые этой задачей ресурсы уменьшилась.