LXF79:Hardcore Linux
|
|
|
Командная строка: секреты Bash
«Это кронтаб. Детки роются в кронтабе». Примерно так бормочет Пол Хадсон (Paul Hudson), весь этот месяц доказывавший своё мужество в неравной схватке с управлением заданиями, навигацией по каталогам Linux и переменными окружения.
Тропа гуру командной строки со всех сторон стеснена недочетами графических инструментов и тиранией невежества. Но если сложности прошлого урока не сбили вас с пути, то осталось изучить последние несколько строк катехизиса команд, и вы получите право хвастаться перед окружающими – и согласитесь, это превесело: быть местным парнем-всезнайкой.
В последнем выпуске мы рассмотрели специфические команды Unix-окружения, вместе с некоторыми, встроенными в Bash. На этот раз я сосредоточусь на том, что предоставляет Bash и как работает система управления заданиями в Unix. Для этого вам могут понадобиться привилегии суперпользователя.
Содержание |
Основы заданий в Bash
Откройте окно терминала и введите такую команду:
yes > /dev/null
Команда yes выводит на экран (или в /dev/null, как в нашем примере) ‘y’, пока вы не прервёте ее (некоторым потребуется время, чтобы понять, в чем ее полезность). Предоставленная сама себе, команда будет выполняться вечно, так что оставим её транжирить циклы процессора, а сами откроем новый терминал и запустим в нём top. Вы должны увидеть, что yes использует до 100% процессорного времени. Затем оставьте окно с top запущенным и вернитесь в терминал с yes. Вам пора уже знать, что нажатие Ctrl+C посылает текущему процессу сигнал SIGINT и обычно приводит к его прерыванию. Можете также нажать Ctrl+\, чтобы послать процессу сигнал SIGQUIT, сигнал немедленно завершит процесс и создаст дамп памяти (core dump). Впрочем, куда важнее, что вы можете использовать Ctrl+Z, чтобы послать SIGSTOP.
Большинство сигналов в Linux отправляются программе и обрабатываются ею. Например, нажатие Ctrl+C посылает SIGINT процессу, а тот его обрабатывает. Процесс может проигнорировать сигнал (в этом случае Ctrl+C ничего не делает), а может выполнить некоторые действия перед завершением работы. Но два сигнала – SIGSTOP и SIGKILL – процессу не отправляются. Вместо этого они передаются непосредственно ядру, потому что требуют внешнего воздействия на процесс. SIGKILL вы уже должны знать по команде kill -9; это сигнал, говорящий: «Любой ценой уничтожь этот процесс». SIGSTOP же говорит: «Хочу временно приостановить этот процесс. Не прибить его, но и не давать ему процессорного времени».
Давайте попробуем применить это к команде yes. Выбрав данный терминал, нажмите Ctrl+Z. Вы должны увидеть такой вывод:
[1]+ Stopped yes > /dev/null
Это означает, что наша команда (yes > /dev/null) остановлена, и на неё можно сослаться как на задание №1. Терминал теперь в ваших руках, так что попробуйте запустить fg (foreground) для реанимации yes. Внимание: отправка SIGSTOP и запуск fg похожи на нажатие паузы на вашем CD-плейере, поскольку процесс на самом деле не прекращает существование, а просто временно приостанавливает работу.
Итак, yes снова работает. Нажмите Ctrl+Z, чтобы опять приостановить процесс, но теперь введите bg, чтобы Bash возобновил его работу и оставил его в фоновом режиме – как будто вы запустили yes > /dev/null &. Теперь yes работает в фоновом режиме, и Ctrl+Z не сможет остановить его. Вместо этого мы должны послать сигнал SIGSTOP непосредственно процессу, используя команду:
kill -SIGSTOP %1
%1 означает, что Bash должен послать сигнал заданию №1, т.е. нашей команде yes. Если вы опасаетесь, что не упомните все цифровые идентификаторы, самое время познакомиться с jobs. У этой команды нет интересных параметров, но она возвращает список всех созданных нами заданий:
paul@Susannah:~$ jobs [1]- Running yes > /dev/null & [2] Stopped top [3]+ Stopped du /
В левом столбце перечислены все запущенные задания, и вы сможете перезапустить любое из них, просто набрав % с последующим номером, например, %1 перезапустит команду yes. В истинном Unix-стиле добавление амперсанда (%1 &) перезапустит задание №1 в фоновом режиме.
Вы, вероятно, недоумеваете, почему задание №1 имеет знак «минус» после номера, задание №2 не имеет никакого знака, а №3 – знак «плюс». Так Bash отмечает, что рассматривается в качестве текущего (+) и предыдущего (-) задания, и вы можете использовать это для краткости. Например, если перевели команду yes в фоновый режим, вы можете воскресить её, набрав %+ (или даже %%). Для ссылки на предыдущее задание используйте %-.
Автоматизация работы
Управление заданиями превосходно работает, когда вы подключены к терминалу, но что если вы хотите, чтобы программы останавливались и запускались, когда вас нет на месте? Есть три способа сделать это в Linux, каждый из которых решает проблему слегка по-своему.
Первый – команда at, позволяющая запланировать программу на запуск в заданное время. Изначально она проектировалась для одноразовых заданий, которые вы хотели выполнить в определённое время (но не сейчас). Второй инструмент – batch, он подобен at, с тем исключением, что время вы не задаёте – задание просто запустится, когда система не загружена. Лучше всего это подходит для ситуаций, когда ресурсы компьютера используются кем-то ещё, а вам нужно на что-то надолго отвлечься. Последний инструмент – Cron, этот планирует задания для регулярного выполнения.
At и batch – милые, удобные инструменты, в то время как Cron выглядит слегка пугающе. Так что давайте начнём с того, что попроще…
At – это где?
Команда at обычно работает интерактивно, то есть вы сначала вызываете программу, указав время, когда задание должно выполниться, затем вводите свои команды и нажимаете Ctrl+D, чтобы сохранить задание. Вот пример «диалога» с at:
paul@Susannah:~$ at midnight at> du / > /home/paul/diskusage at <EOT> job 4 at 2006-03-24 00:00
В первой строке я запускаю at и указываю полночь (midnight) как время старта для задания. При этом at запустится, и появится приглашение at>, показывающее, что можно вводить содержимое задания. Задание, которое я хочу выполнить в полночь – выяснить, сколько дискового пространства используется на моём компьютере, так что я запускаю du и перенаправляю её вывод в файл в моём домашнем каталоге. <EOT> – это я нажал Ctrl+D, что приводит к сохранению задания, выводу его номера и сообщению, когда оно будет выполнено (сегодня в полночь).
Узнать, какие задания уже поставлены в очередь, вы можете, набрав atq, которая распечатает что-то наподобие
4 2006-03-24 00:00 a paul
Первое, второе и четвёртое поля – это соответственно номер задания, время, когда оно будет выполнено, и кто его создал, но о третьем поле нужно сказать особо: это приоритет задания. В Linux можно выбрать много очередей заданий, и чем дальше буква от начала алфавита, тем ниже приоритет. Очередь «a» имеет наивысший приоритет, и будет исполнена с нормальным для пользователя значением nice (то есть так быстро, как только сможет).
Если вы дождётесь полуночи, ваше задание будет выполнено, как и планировалось. Но если вы передумаете, используйте команду atrm, чтобы удалить задание:
atrm 4
Есть несколько способов указать время в at, и midnight – лишь один из них. Из предопределённых есть tomorrow (завтра), noon (полдень) и teatime (4 часа вечера), но вы можете указывать и точное время, например, 16:00 (те же 4 вечера) или комбинировать эти значения (16:00 tomorrow). Простейший способ – указывать относительное время, используя now (сейчас), например, так:
at now + 5 minutes at now + 3 hours at now + 4 weeks
Если время выполнения для вас не имеет значения, забудьте про at и используйте batch. Различие заключается в том, что batch начнёт выполнять ваши задания сразу же, как только загрузка системы опустится ниже 0,8 (т.е. машина будет не слишком занята). Синтаксис намного проще, поскольку не нужно указывать время: просто наберите batch, нажмите Enter, добавьте свои команды и нажмите Ctrl+D, чтобы сохранить задание.
Введя atq, вы увидите ваше задание в очереди «B», что означает запуск с более низким приоритетом, чем у других заданий и большинства программ в системе. По этой причине ваше задание стартует только тогда, когда система бездействует, но если оно запустится, а в следую щую секунду машину потребует другая работа, ваше задание тихонько переберется в фоновый режим и отдаст ресурсы процессора. Оно не останавливается, но из-за более низкого приоритета получит намного меньше процессорного времени.
Никто не любит вводить одну и ту же команду снова и снова, так что если вы хотите, чтобы at или batch читали ваши задания из файла, просто используйте -f имяфайла перед указанием времени, например, так:
at -f myjob.job tomorrow batch -f myjob.job
Нет ничего прекраснее, чем заставить ваш компьютер делать кучу работы за вашей спиной, полностью автоматически, пока вы играете в UT. Волшебной программой, осуществляющей это, является Cron, демон времени. Каждую минуту каждого часа, ежедневно, на протяжении всего года, миллионы демонов Cron по всему миру проверяют, нужно ли что-то сделать, затем, разочаровавшись, снова бездействуют 60 секунд. Не позволяйте вашему демону скучать – пусть он немного порезвится!
Вот работа для Cron
Задания Cron можно разделить на два типа: пользовательские и системные. Большинство дистрибутивов Linux поставляются с Cron, способным на обе роли, то есть каждый может назначать свои персональные задания, и сама система тоже будет регулярно что-нибудь запускать. Вам потребуются права суперпользователя, чтобы изменять системные задания, поскольку они отвечают за важные вещи – обновление базы данных locale, генерирование базы данных man, скачивание и применение обновлений безопасности, и т.д. Многие из них, вероятно, уже есть в вашем дистрибутиве, и мы довольно скоро их рассмотрим.
Но сначала рассмотрим пользовательский Cron – регулярные задания, назначаемые пользователем для выполнения повседневных задач. Например, часто требуются ночные сборки программного проекта. Если вы тестируете KDE и приближается дата выпуска, вы, вероятно, захотите скачивать новый релиз каждый день, компилировать его и тестировать, выискивая ошибки. Загрузка выполняется довольно просто: возьмите Konstruct, отредактируйте конфигурационный файл так, чтобы выполнялась проверка последней версии исходного кода в Subversion, и пересоберите. Но сборка KDE может потребовать более четырёх часов, в зависимости от числа изменений и скорости вашей машины. Вот и работа для Cron!
Введите crontab -e, чтобы отредактировать ваш персональный crontab (так называется файл Cron со списком ваших заданий). Если у вас его ещё нет, он будет создан. Теперь – самая сложная часть: хитрый формат файла crontab. Наберите в нём такую строку:
* * * * * du -h / > /home/paul
Вместо paul укажите ваше собственное имя [пользователя]. Часть du и последующие символы – это команда, которую Cron должен выполнить, а все эти звёздочки определяют время, когда она должна выполняться. Это смешнее всего! По порядку:
- Минута (0-59)
- Час (0-23)
- День (1-31)
- Месяц (1-12)
- День недели (0-7, как 0, так и 7 соответствуют воскресенью)
Звёздочка означает «все значения», так что «* * * * *» означает «каждую минуту каждого часа ежедневно каждый месяц, независимо от дня недели». Следующее задание будет выполняться каждую субботу в полдень:
0 12 * * 6 du -h / > /home/paul
Cron перечитывает свои конфигурационные файлы раз в минуту, но не сразу выполняет все обнаруженные задания. То есть, если сейчас без десяти секунд полночь и вы установите задание на полночь, оно будет выполнено через 24 часа + 10 секунд. [Точнее, при первом после добавления задания запуске выполняется подготовка заданий, а при втором (через минуту) – их выполнение, – прим. перев.]
Помимо указания точного времени для настройки простых заданий, вы можете определить и более сложные выражения, используя дефисы и запятые. Например, можно создать четыре задания Cron для запуска сценария в 11, 12, 13 и 14 часов, а можно просто записать задание таким образом:
0 11-14 * * * du -h / > /home/paul
Запятые позволяют указывать конкретные значения вместо диапазона, так что мы можем сделать то же самое другим способом:
0 11,12,13,14 * * * du -h / > /home/paul
Но и без этого вы можете создать столько заданий, сколько захотите – просто вводите их, каждое в свою строку, в ваш crontab. Просмотреть текущий crontab позволяет команда crontab -l, но она просто распечатает то же самое, что вы увидите при редактировании файла, так что проку от нее мало.
Корни Cron
Раз уж вы освоили мощь Cron с точки зрения пользователя, пора браться за более «продвинутую» вещь: редактирование системных файлов crontab. Да, их несколько – во многих системах есть скрипты, содержащие почасовые, ежедневные, еженедельные и даже ежемесячные задания. Откройте в своём любимом текстовом редакторе файл /etc/crontab, и вы увидите нечто вроде
17 * * * * root run-parts --report /etc/cron.hourly 25 6 * * * test -x /usr/sbin/anacron || run-parts --report /etc/cron.daily 47 6 * * 7 test -x /usr/sbin/anacron || run-parts --report /etc/cron.weekly 52 6 1 * * test -x /usr/sbin/anacron || run-parts --report /etc/cron.monthly
То есть часовые задания выполняются в 17 минут каждого часа, ежедневные – каждое утро в 6:25, еженедельные – по воскресеньям в 6:47 и ежемесячные – в 6:52 первого числа месяца. На вид время выполнения задано «с потолка», но в нем есть свой смысл – большинство заданий выполняется утром, когда нагрузка минимальна, и они запускаются в разное время, чтобы избежать столкновения между собой.
В системном файле есть одно дополнительное поле, используемое для указания имени владельца задания. В нашем примере везде стоит root, но вы можете изменить его на более подходящее для вашего собственного перечня.
Если вы не сталкивались с этой утилитой раньше, то поясним, что run-parts выполняет все программы в заданном каталоге и может дополнительно предоставлять отчёт (--report) об этом выполнении.
Она идеальна для заданий Cron, поскольку может разделять их по каталогам /etc/Cron.hourly, /etc/Cron.daily и так далее. Если вы хотите добавить собственное задание в список ежечасных, просто скопируйте исполняемый сценарий в /etc/Cron.hourly и предоставьте run-parts сделать всё остальное.
Помимо настройки системных заданий, права root дают нам ещё одну привилегию: мы можем решать, кому позволить, а кому запретить планирование заданий. Каждый пользователь, имеющий право использовать at и batch, должен быть указан в файле /etc/at.allow. Но если вы попытаетесь открыть этот файл (как root), то, вероятно, обнаружите, что его вообще не существует. Это потому, что по умолчанию каждый пользователь рассматривается как имеющий право работать с at и batch, если он явно не указан в файле /etc/at.deny [который по умолчанию присутствует, – прим. перев.]. В представленной таблице разъясняется, как работают права.
Как at.allow и at.deny распоряжаются правами на задания
at.allow | at.deny | Можете ли вы использовать at/batch? |
---|---|---|
Не существует | Не существует | Нет |
Не существует | Существует, и вы в нём | Нет |
Не существует | Существует, но вас там нет | Да |
Существует, но пуст | Существует, и вы в нём | Нет |
Существует, но пуст | Существует, но вас там нет | Нет |
Существует, и вы в нём | Существует, но вас там нет | Да |
Существует, но вас там нет | Существует, и вы в нём | Нет |
Существует, и вы в нём | Существует, и вы в нём | Да |
Учитесь запоминать
Вспомните лекции по информатике. В частности, абстрактные типы данных. Вы должны помнить их – стеки, очереди и т.д. Если же вы спали на лекциях (думаю, большинство из нас так и делало), напомню, что стеки – это массивы типа «Последний пришёл – первый вышел», то есть поместив в стек элемент A, затем B, а затем C, извлечь их оттуда вы сможете в порядке C, B, A. Элемент A не достать, пока не извлекут элементы C и B.
Всё это я говорю потому, что мы частенько рассматриваем навигацию по каталогам Linux как совершенно произвольную и сложную для отслеживания операцию, хотя на самом деле можно трактовать наши перемещения как стек. Bash выполняет всё это для нас с помощью команд pushd и popd, которые изменяют текущий каталог. Вы помещаете (push) каталоги в стек Bash (перемещаясь в них и добавляя их к списку сохранённых каталогов), и затем извлекаете (pop) их из стека (удаляя его и возвращаясь в предыдущий каталог).
Это лучше продемонстрировать на примере:
paul@Susannah:~$ pushd /etc/init.d /etc/init.d ~ paul@Susannah:/etc/init.d$ pushd /var/log /var/log /etc/init.d ~ paul@Susannah:/var/log$ pushd /usr/local/bin /usr/local/bin /var/log /etc/init.d ~ paul@Susannah:/usr/local/bin$ popd /var/log /etc/init.d ~ paul@Susannah:/var/log$ popd /etc/init.d ~ paul@Susannah:/etc/init.d$ popd ~ paul@Susannah:~$
Первоначально я нахожусь в моём домашнем каталоге, но хочу перейти в /etc/init.d. Если я выполню cd /etc/init.d, я тут же потеряю путь, где я был до этого, поэтому я использую pushd /etc/init.d, которая делает текущим /etc/init.d, но сохраняет мой предыдущий каталог в стеке каталогов. Обратите внимание, что Bash выводит на экран мой стек – сейчас это /etc/init.d ~, что означает: «Ты сейчас в /etc/init.d, а до этого был в ~».
Теперь я снова использую pushd /var/log, чтобы сменить каталог, и Bash добавит его в список. Далее, я таким же образом перехожу в /usr/local/bin, и теперь у нас четыре элемента в стеке каталогов. Пора воспользоваться popd. Каждый раз, когда я вызываю popd, верхний элемент (каталог слева в стеке) удаляется, и я возвращаюсь в предыдущий каталог. Из /usr/local/bin я перехожу в /var/log, затем в /etc/init.d, и, наконец, назад в ~, мой домашний каталог – и стек опять пуст.
Есть ещё несколько трюков, которые можно выполнить с помощью pushd и popd. Во-первых, простой ввод pushd будет переключать вас между двумя верхними каталогами в стеке, перемещая вас туда и обратно без изменения остальной части стека. С помощью popd вы можете удалить каталоги из стека, введя popd +X, где X – элемент стека, подлежащий удалению. Нумерация элементов в стеке начинается с нуля, так что самый верхний каталог (текущий) будет иметь индекс 0, следующий – 1, и т.д. Таким образом, ввод popd +2 удалит из стека третий элемент.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Сохранение окружения
Bash обеспечен полным комплектом переменных окружения – введите set, и вы поймёте, о чем я говорю. Многие из них устанавливаются автоматически, такие как USER (ваше имя пользователя), LINES (число строк, отображаемых вашим терминалом), HOME (ваш домашний каталог) и т.д. Некоторые переменные окружения уже установлены, но часто меняются, например, PATH, сохраняющая все каталоги, где будет выполняться поиск исполняемых файлов. Другие переменные окружения полностью определяются пользователем – вы можете устанавливать собственные значения, чтобы хранить интересующие вас данные.
Изменение таких переменных, как PATH, бывает весьма полезным, особенно учитывая, что Bash различает операции «установка переменной для одной команды» и «установка переменной для всех команд в текущем сеансе». Попробуйте сами:
cp /bin/mount ~/date PATH=. date date
Здесь /bin/mount копируется в ваш домашний каталог и переименовывается в date. Но date – это исполнимая программа в /bin, так что второй командой мы говорим: «Установи наш путь только на текущий каталог (так что ~/date будет читаться, а /bin/date нет) и затем исполни команду date». В результате мы запустим нашу копию mount. Но если вы выполните следующую команду, date, вы увидите нормальный вывод программы date, поскольку переменная PATH вернётся к своему обычному значению. Если вы хотите установить переменную на весь сеанс, используйте export, например, так:
export PATH=/path/to/someplace:$PATH
Эта команда добавит /path/to/someplace в начало списка каталогов в PATH, дописав оставшиеся значения в конец.
Некоторые дистрибутивы (самый злостный преступник, пожалуй, SUSE) доводят использование переменных окружения до крайности и записывают в них сложные функции, загромождающие вывод простой и милой команды set, но не пугайтесь: воспользуйтесь графическим терминалом, установите буфер вывода побольше и прокручивайте окно назад, пока не найдёте то, что вас интересует.