htop и многое другое на пальцах

htop на Ubuntu Server 16.04 x64

Ниже скриншот htop, который я буду рассматривать в статье.

Uptime

Uptime показывает время непрерывной работы системы. Это можно узнать и командой uptime.

Где же программа uptime это берёт? Она считывает информацию из файла /proc/uptime.

Первое число — количество секунд работы системы. Второе же показывает сколько секунд система находилась в бездействии. Стоит отметить, что на системах с несколькими процессорами, второй показатель может оказаться больше, чем первый, так как это сумма по процессорам.

Как я об этом узнал? Я посмотрел какие файлы открывает uptime при запуске. Для этого, можно воспользоваться утилитой strace.

Будет много вывода, лучше сделать grep для поиска системного вызова open. Но это не совсем сработает, т.к. по умолчанию он выводит в стандартный поток ошибок (stderr). Можно перенаправить stderr в стандартный поток с помощью 2>&1.

Результат таков:

Тут содержится упомянутый файл /proc/uptime. Оказалось, что достаточно запустить strace -e open uptime и не мучиться с grepом.

Если можно взять это прямо из файла, то зачем нужна утилита uptime? Дело в том, что uptime форматирует вывод в читаемом виде, тогда как секунды в файле удобно использовать при написании собственных скриптов и программ.

Load average

Помимо времени непрерывной работы, uptime показывает и среднюю загрузку системы, они отображены как 3 числа.

А взяты они из файла /proc/loadavg. Если еще раз посмотреть на вывод strace, то можно заметить, что этот файл тоже был открыт.

Первые 3 числа измеряют среднюю загрузку системы за последние 1, 5 и 15 минут. 4-ый параметр это количество активных процессов и их общее число. Последнее число это ID последнего использованного процесса.

Начнём с конца.

Когда запускается процесс, ему присваивается ID. Как правило, они идут в возрастающем порядке, за исключением случаев, когда число исчерпалось и системе приходится начинать отсчёт заново. ID 1 присваивается процессу /sbin/init, который запускается при старте.

Взглянем ещё раз на /proc/loadavg и попробуем запустить команду sleep в фоновом режиме. При запуске в фоновом режиме, можно увидеть ID процесса.

Таким образом, 1/123 означает, что 1 процесс выполняется или готов к выполнению, а всего их 123.

Когда при запуске htop, вы видите, что выполняется только один процесс, это сам процесс htop.

Если запустить sleep 30 и открыть htop, то число выполняющихся процессов всё равно будет 1. Это потому, что процесс sleep не выполняется, а «спит», т.е. находится в состоянии покоя, иными словами ждёт определённого события. Выполняющийся или активный процесс, это процесс который на данный момент обрабатывается в процессоре (CPU), либо ждёт своей очереди в процессоре.

Попробуйте запустить cat /dev/urandom > /dev/null, где генерируемые случайные байты записываются в особый файл, считывание из которого невозможно. Тогда вы увидите, что выполняющихся процессов теперь уже 2.

Так, активных процессов ровно 2 (генератор случайных чисел и утилита cat, которая читает файл /proc/loadavg), еще можно заметить что средняя загрузка возросла.

load average это средняя загрузка системы на протяжении определённого периода времени.

Число загрузки считается как сумма количества процессов, которые запущены (выполняются или находятся в ожидании запуска) и непрерываемых процессов (о видах процессов будет рассказано ниже). Т.е. это просто число процессов.

А средняя загрузка получается просто усреднённое значение за 1, 5 и 15 минут, так?

Оказывается, не всё так просто.

Говоря математическим языком, все три значения усредняют среднюю загрузку за всё время работы системы. Они устаревают экспоненциально, но с разной скоростью. Таким образом, средняя загрузка за 1 минуту это сумма 63% загрузки за последнюю минуту + 37% загрузки с момента запуска без учёта последней минуты. То же соотношение верно и для 5, 15 минут. Поэтому не совсем верно, что средняя загрузка за последнюю минуту включает активность только за последнюю минуту, но бОльшей частью за последнюю минуту.

Вы это знали?

Вернёмся к генератору случайных чисел.

Хотя это не совсем правильно, но вот как я упростил для понимания показатель средней загрузки.

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

В моей системе это означает что процессор загружен на 100%, т.к. процессор один, а выполнять он может только один процесс за раз.

Если бы процессоров было 2, то загрузка соответственно была бы 50%, т.к. можно было бы одновременно выполнять 2 процесса. Максимальная средняя загрузка (100% использования CPU) системы с двумя процессорами составляет 2.00.

Количество процессоров в системе можно узнать в левом верхнем углу htop или при помощи nproc.

Процессы

В правом верхнем углу, htop показывает общее количество процессов и сколько из них активны. Но почему там написано задания [Tasks], а не процессы?

Задание это синоним процесса. В ядре Linux процессы это и есть задания. htop использует термин задания, возможно, потому, что это название короче и экономит немного места.
В htop можно увидеть и потоки [threads]. Для переключения этой опции нужно использовать комбинацию Shift+H. Если отображается что то вроде Tasks: 23, 10 thr, то это значит они видимы.

Отображение потоков выполнения ядра [kernel threads] можно включить комбинацией Shift+K, и тогда задания будут выглядеть как Tasks: 23, 40 kthr.

ID процесса / PID

При каждом запуске процесса, ему присваивается идентификатор (ID), сокращенно PID.

Если запускать программу в фоновом режиме (&) из bash, то номер задачи[job] выводится в квадратных скобках, а рядом с ним PID процесса.

Ещё один способ, это использовать переменную $! в bash, которая хранит PID последнего процесса, запущенного в фоне.

ID процесса очень полезна. С помощью него можно узнать подробности процесса и управлять им.

Существует псевдо файловая система procfs, с помощью которой программы могут получить информацию от ядра системы путём чтения файлов. Чаще всего она монтируется в /proc/ и для пользователя выглядит как обычный каталог, который можно смотреть командами, такими как ls и cd.

Вся информация о процессе находится в /proc/<рid>/.
$ ls /proc/12503

Например в /proc/<рid>/cmdline содержится команда при помощи которой процесс запустился.

Эмм…, не совсем так. Разделителем тут служит байт \0,

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

В каталоге процесса могут быть и ссылки! Для примера, cwd ссылается на текущий рабочий каталог, а exe на запущенный исполняемый файл.

Таким образом утилиты htop, top, ps и другие показывают информацию о процессе, они просто читают /proc/<рid>/<файл>.

Дерево процессов

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

Если нажать F5 в htop, то можно увидеть иерархию процессов.

Тот же эффект и от флага f команды ps.

Либо pstree.

Если вы когда нибудь задумывались, почему bash или sshd являются родительскими для некоторых процессов, то вот почему.

Ниже я написал, что происходит, если вы, к примеру, вызовите date из консоли bash.

  • bash создаст новую копию своего процесса (используя системный вызов fork)
  • Затем он переместит исполняемый файл /bin/date в память (при помощи системного вызова exec).
  • bash, как родительский процесс будет ожидать окончания работы дочернего.

Таким образом, /sbin/init, у которого ID 1, начал выполняться при старте системы и породил демона SSH sshd. После подключения к системе, sshd породит процесс для текущей сессии, который в свою очередь запустит консоль bash.

Я предпочитаю использовать древовидную структуру в htop когда хочется увидеть все потоки.

Владелец процесса

У каждого процесса есть владелец — пользователь. У пользователей, в свою очередь, существуют численные ID.

Можно воспользоваться командой id, чтобы узнать имя этого пользователя.

Как выяснилось, id берёт эту информацию из файлов /etc/passwd и /etc/group.

Это обычные текстовые файлы, в которых ID привязаны к именам пользователей.

passwd? Но где пароли? А они на самом деле в /etc/shadow.

Если вы запустите программу, то она запустится от вашего имени, даже если вы не являетесь её владельцем. Если же вам нужно запустить её как root, то нужно использовать sudo.

Но что, если нужно запустить несколько программ от имени других пользователей? Можно запустить консоль от их имени, если воспользоваться командами sudo bash или sudo -u user bash.

Если не хочется каждый раз вводить пароль администратора при запуске программ, то можно отключить эту функцию, добавив своё имя пользователя в файл /etc/sudoers.

Давайте попробуем.

Да, точно, это можно сделать только с привилегиями root.

Что за…?

Тут мы пытаемся вызвать echo от имени администратора, но при этом пишем в файл /etc/sudoers всё так же от нашего имени.

Как правило, есть 2 выхода из данной ситуации:

  • echo «$USER ALL=(ALL) NOPASSWD: ALL» | sudo tee -a /etc/sudoers
  • sudo bash -c «echo ‘$USER ALL=(ALL) NOPASSWD: ALL’ >> /etc/sudoers»

В первом случае, tee -a запишет из стандартного потока ввода в файл от имени администратора.

Во втором случае, мы запускаем консоль от имени администратора и просим выполнить команды (-c) и все команды выполнятся от имени root. Обратите внимание на расстановку кавычек «/, при помощи которых переменная $USER разыменуется правильно.

Допустим, вы захотели поменять свой пароль. Команда passwd вам в помощь. Она сохранит пароль в файле /etc/shadow, который мы видели выше.

Этот файл доступен для записи только для root:

Как же это возможно, что программа запускаемая от имени пользователя может записывать в защищённый файл?

Я уже говорил, что при вызове, программа запускается от имени пользователя, запускающего её, даже если она принадлежит другому пользователю.

Оказывается, это поведение можно изменить правками разрешения файла. Давайте посмотрим.

Обратите внимание на символ s. Она была добавлена при помощи sudo chmod u+s /usr/bin/passwd. И означает, что исполняемый файл будет всегда запускаться от имени владельца, в данном случае это root.

Так называемые исполняемые файлы setuid можно искать при помощи find /bin -user root -perm -u+s.

Так же это можно осуществить и для групп (g+s).

Состояния процесса

Дальше, мы будем разбираться со столбцом состояния процессов в htop, в котором, на примере, находятся символы S.

Возможные значения состояния:

  • R — [running or runnable] запущенные или находятся в очереди на запуск
  • S — [interruptible sleep] прерываемый сон
  • D — [uninterruptible sleep] непрерываемый сон (в основном IO)
  • Z — [zombie] процесс зомби, прекращенный, но не забранный родителем
  • T — Остановленный сигналом управления заданиями
  • t — Остановленный отладчиком
  • X — Мёртвый (не должен показываться)

Они отсортированы по тому, как часто я их обычно вижу.

Заметьте, что при запуске ps, он может ещё показывать подсостояния как Ss, R+, Ss+ и т.д.

 

R — Запущенные или в очереди

Процессы в этом состоянии либо запущены, либо находятся в очереди для запуска.

Что это значит?

Когда вы компилируете код, то на выходе получаете исполняемый файл в виде инструкций для процессора. При запуске, этот файл помещается в память, где процессор выполняет эти инструкции, проще говоря занимается вычислениями.

S — Прерываемый сон

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

Для примера можно взять утилиту sleep из coreutils. Он будет находится в состоянии сна определенное количество секунд.

Так это прерываемый сон, как же его можно прервать? С помощью сигнала.

Послать сигнал с помощью htop можно нажав клавишу F9 и выбрав нужный вид сигнала в меню.

Передача сигнала, так же известна как команда kill, потому что это на самом деле системный вызов, который может послать сигнал процессу. Существует одноимённая программа /bin/kill, которая может исполнить системномный вызов из пользовательского окружения и по умолчанию посылает сигнал TERM, который уничтожает процесс, убивает его.

Сигнал это всего лишь число. Числа сложно запомнить, поэтому их назвали именами. Их имена обычно пишут заглавными буквами и могут быть с префиксом SIG.

Часто используемые сигналы, это: INT, KILL, STOP, CONT, HUP.

Попробуем прервать спящий процесс, послав ему сигнал INT, он же SIGINT, просто 2, или сигнал прерывания с терминала.

Этот же сигнал посылается, если нажать комбинацию CTRL+C. bash пошлёт сигнал SIGINT процессу на переднем плане, точно так же, как мы это сделали вручную.

Кстати, в bash команда kill встроена, хотя во многих системах есть программа /bin/kill. Почему? Чтобы можно было «убить» процесс даже если превышен лимит на количество создаваемых процессов.

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

Возможно, вы встречали такое исключение при запуске скриптов на Python:

Но существует сигнал способный остановить процесс, не дав ему возможности на него ответить. Это сигнал KILL.

 

D — непрерываемый сон

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

При этом состоянии процесс ожидает и не может быть прерван, например, если событие продолжения вот вот наступит, такое как чтение/запись на диск. Как правило, это происходит за доли секунды.

На StackOverflow есть хороший ответ:

Непрерываемые процессы обычно находятся в ожидании IO после page fault. Процесс не может быть прерван в это время сигналом, потому что не сможет их обработать. Если бы он мог, то снова возник бы page fault и всё бы осталось как есть.

Другими словами, это может случиться, если, например, использовать протокол сетевого доступа NFS и требуется время для чтения/записи с/на него.

По своему опыту могу сказать, что такое случается когда процесс часто подкачивается, т.е. для него недостаточно свободной памяти.

Попробуем вызвать это состояние.

8.8.8.8 это публичный DNS от Google. Там нет NFS, но это нас не остановит.

Как же узнать, что заставляет процесс оказаться в таком состоянии? strace!

Вызовим strace для команды ps выше.

И тут мы увидим, что системный вызов mount блокирует процесс.

А mount, кстати можно вызвать с опцией intr, чтобы его можно было прерывать: sudo mount 8.8.8.8:/tmp /tmp -o intr.

Z — Зомби процесс

Когда процесс заканчивает свою работу с помощью exit и у неё остаются дочерние процессы, дочерние процессы становятся в состоянии зомби.

  • Абсолютно нормально, если зомби процесс существует недолго
  • Зомби процессы которые существуют долгое время, могут говорить о баге в программе
  • Зомби процессы не используют память, только лишь ID процесса
  • Зомби процесс нельзя «убить»
  • Можно вежливо попросить родительский процесс избавиться от зомби (послав SIGCHLD)
  • Можно завершить родительский процесс, чтобы избавиться от обоих

Я продемонстрирую это, написав небольшой код на С.

Устанавливаем компилятор С, GNU C Compiler (GCC).

Скомпилируем и запустим программу

Посмотрим на иерархию процессов

У нас есть зомби! Когда родительский процесс завершается, зомби исчезает.

Если заменить sleep(20) инструкцией while (true), зомби исчезнет сразу.

При вызове exit, освобождается вся занимаемая память и ресурсы, чтобы они были доступны другим. Почему же нужны тогда процессы зомби?

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

Почему же тогда принудительно не разбудить процесс и завершить его? По той же причине, по которой вы не избавитесь от своего ребёнка, если он вас не слушается. Всё может закончится плохо.

T — Остановлен сигналом управления заданиями

Я открыл два терминала и могу посмотреть на свои процессы командой ps u.

Ниже я опущу упоминание процессов -bash и ps.

Теперь в одном из терминалов запустим cat /dev/urandom > /dev/nul. Его состояние будет R+, из чего следует что он активен.

Нажмём CTRL+Z, чтобы остановить процесс.

Сейчас, он в состоянии T. Если нужно продолжить процесс, то можно вызвать fg в первом терминале.

Есть и другой способ останова процессов, для этого нужно послать им сигнал STOP с помощью kill, а для продолжения, соответственно, сигнал CONT.

t — Остановлен отладчиком

Для начала установим отладчик GNU Debugger (gdb)

Запустим программу для прослушивания порта 1234.

Он находится в состоянии сна, потому как ждёт входящих сообщений.

Запустим отладчик и привяжем его к процессу с PID 3905.

Теперь процесс будет прослеживаться [trace] в отладчике и его состояние изменится на t.

 

Время обработки процесса

Linux — многозадачная операционная система, это означает что даже если процессор один, то можно одновременно запускать на нём  несколько заданий. Например, можно подключиться к удалённому серверу через SSH и посмотреть на вывод htop, а при этом сам сервер будет показывать ваш блог читателям в интернете.

Как же возможно, что единственный процессор может одновременно выполнять несколько заданий?

Разделением времени.

Каждый процесс выполняется определённый интервал времени, при котором другие приостановлены, затем выполняется следующий процесс и т.д.

Как правило, интервал времени выполнения составляет миллисекунды, поэтому пользователь этого и не заметит, если, конечно же, система не нагружена.

Любезность и приоритет процессов

Когда количество заданий превышает количество процессоров, но выполнить их все необходимо, нужно каким то образом определить порядок их выполнения. За это отвечает планировщик заданий.

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

Пользователь, как правило, не может прямо влиять на планирование, но может подсказать какой из процессов ему особо важен и планировщик, возможно, прислушается к нему.

Любезность или приоритет nice (NI) это приоритет процесса в пространстве пользователя, варьирующаяся от -20, что есть самый высокий приоритет, до 19, соответственно наименьший приоритет. Это может запутать, но представьте это именно как любезность, т.е. чем процесс любезнее, тем он уступчивее другим процессам.

Из того, что я прочёл на StackOverflow и других сайтах, следует что увеличение любезности процесса на 1 ведёт к уступке 10% времени работы процессора.

Приоритет (PRI) же в свою очередь это параметр приоритета в пространстве ядра. Приоритет варьируется от 0 до 139. Приоритеты от 0 до 99 зарезервированы для процессов реального времени, а выше, т.е от 100 до 139, для пользовательских.

Можно изменить любезность процесса, и тогда, возможно, ядро примет это к сведению, но сам приоритет менять нельзя.

Соотношение любезности и приоритета следующее: PR = 20 + NI.
Таким образом область определения PR = 20 + (-20 to +19) лежит в отрезке от 100 до 139.

Можно установить любезность процесса непосредственно перед запуском.

А менять любезность во время выполнения можно с помощью renice.

http://askubuntu.com/questions/656771/process-niceness-vs-priority

Память — VIRT/RES/SHR/MEM

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

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

Я хочу сказать, что из-за этого не совсем легко понять сколько же именно памяти использует процесс. А что насчёт общих [shared] библиотек и памяти, выгруженной на диск? Но, к счастью, ядро и, в частности, htop позволяют извлечь некоторую информацию чтобы понять аппетит процесса по отношению к памяти.

VIRT/VSZ — Виртуальный образ

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

Таким образом VIRT это всё, что используется процессом.

Если приложение запрашивает 1 Гб памяти, но использует при это только 1 Мб, то память VIRT будет отображаться всё равно как 1 Гб. Даже если оно вызовет mmap для файла весом в 1 Гб и никогда им не воспользуется, то VIRT всё равно останется 1 Гб.

В большинстве случаев этот показатель бесполезен.

RES/RSS — Резидентная память

Память RSS [resident set size] это область, которая не выгружена на диск и находится в оперативной памяти.

RES, возможно, лучше отображает реальное использование памяти процессора чем  VIRT, но нужно иметь ввиду:

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

Если процесс использует 1 Гб памяти и вызывает fork(), то в результате у обоих процессов значение RES будет 1 Гб, в то время как в оперативной памяти будет занято только 1 Гб, потому что в Linux есть механизм копирования при записи [copy-on-write].

SHR — Разделяемая память

Объём памяти, который может быть совместно использован другими процессами.

Затем

И

(прим. Этот раздел не дописан до конца, как только статья обновится, я опубликую обновления)

MEM% — Использование памяти

Процент использования физической памяти. Это RES, делённый на общий объём оперативной памяти.

Если, например, RES составляет 200М и в системе установлено 8 Гб памяти, то MEM% будет 200/8192*100 = 2.4%

Процессы

Я запустил виртуальную машину с Ubuntu Server в Digital Ocean. Какие же процессы запускаются при старте системы? Необходимы ли они?

Ниже приведён анализ процессов, которые запускаются на чистой версии машины с Ubuntu Server 16.04.1 LTS x64 в Digital Ocean.

До

/sbin/init

Эта программа координирует все остальные приложения при запуске и конфигурирует окружение пользователя. После запуска, она становится родителем или прародителем всех автоматически запускающихся процессов.

Это же systemd?

Да, он самый. Что произойдёт, если его остановить? Ничего.

/lib/systemd/systemd-journald

ystemd-journald это системная служба, которая собирает и сохраняет логи. Она создаёт структурированные, проиндексированный журналы на основе информации, полученной с разных источников и управляет ими.

Другими словами,

Одним из основных преимуществ journald является замена обычных текстовых файлов логов специально отформатированными структурированными сообщениями. Это позволяет администраторам эффективнее работать с журналами событий.

Если нужно найти событие, лучше использовать journalctl.

  • journalctl _COMM=sshd поиск по sshd
  • journalctl _COMM=sshd -o json-pretty поиск по sshd в JSON
  • journalctl —since «2015-01-10» —until «2015-01-11 03:00»
  • journalctl —since 09:00 —until «1 hour ago»
  • journalctl —since yesterday
  • journalctl -b история с момента запуска системы
  • journalctl -f чтобы следить за логами
  • journalctl —disk-usage
  • journalctl —vacuum-size=1G

Впечатляюще. Этот процесс, кажется, нельзя остановить или убрать, можно лишь отключить ведение истории.

/sbin/lvmetad -f

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

Но что такое LVM [Logical Volume Management] (Менеджер логических томов)? Можно считать, что LVM это динамические разделы, что подразумевает создание/изменение/удаление разделов, так называемых «логических томов» из командной строки на лету, без надобности перезагрузки системы.

Звучит так, что нужен он только если пользоваться LVM.

 

/lib/systemd/udevd

systemd-udevd следит за событиями uevents ядра. Для каждого события, systemd-udevd запускает соответствующую инструкцию на основе правил в udev.

udev это диспетчер устройств ядра Linux. Как преемник devfsd и hotplug, udev в основном работает с устройствами в каталоге /dev.

Я не уверен о его необходимости в виртуальной среде.

/lib/systemd/timesyncd

systemd-timesyncd это системная служба которая синхронизирует локальное время с удалённым сервером NTP.

Он заменил ntpd.

Посмотрим на открытые порты системы:

Красота! В Ubuntu 14.04 это выглядело так:

Брр.

/usr/sbin/atd -f

atd запускает задания, назначенные в определённое время с помощью at.

В отличии от cron, который исполняет задания с периодичностью, at единовременно выполняет задание в определённое время.

Кстати, я ни разу не использовал его до этого момента.

 

/usr/lib/snapd/snapd

Snappy Ubuntu Core это новое исполнение Ubuntu с обновлёнными решениями — минимальный образ сервера с теми же библиотеками что и Ubuntu, но приложения предоставляются через более простой механизм.

Что?

Разработчики нескольких дистрибутивов Linux и компании призвали к сотрудничеству для создания универсального формата «snap» для пакетов Linux, чтобы один и тот же бинарный пакет успешно и безопасно работал на любом компьютере, сервере, облаке и устройстве с Linux.

Оказывается, это упрощенный пакет deb, где нужно прикреплять все зависимости. Я никогда не пользовался snappy для установки или создания приложений на серверах.

 

/usr/bin/dbus-daemon

D-Bus — система межпроцессного взаимодействия, которая позволяет приложениям в операционной системе общаться друг с другом.

Я так понимаю, что это нужно только для домашнего окружения, но зачем это серверу веб приложений?

Интересно, который сейчас час и синхронизируется ли время с NTP?

Упс, возможно, это стоило оставить.

/lib/systemd/systemd-logind

systemd-logind это системная служба, управляющая авторизациями в систему.

/usr/sbin/cron -f

cron — демон для запуска заданий по расписанию (Vixie Cron)
-f — не демонизировать процесс.

С помощью cron можно запускать задания с периодичностью.

Чтобы редактировать расписание, можно использовать crontab -e, я предпочитаю каталоги /etc/cron.hourly, /etc/cron.daily, и т.д.

А историю запуска можно найти так:

  • grep cron /var/log/syslog или
  • journalctl _COMM=cron или даже так
  • journalctl _COMM=cron —since=«date» —until=«date»

Наверняка, cron вам понадобится.

Но если нет, то перед удалением, его нужно остановить и отключить

Иначе при попытке удаления командой apt remove cron, он попытается установить postfix!

Похоже, что cron нужен сервер почты для рассылки.

 

/usr/sbin/rsyslogd -n

Rsyslogd — утилита помогающая вести логи.

Другими словами, это то, что создаёт файлы в /var/log/, такие как /var/log/auth.log для сообщений о попытках аутентификации пользователя через SSH.

Файлы конфигурации тут /etc/rsyslog.d.

Можно настроить rsyslogd таким образом, что он будет отправлять файлы на удалённый сервер, создав тем самым централизованную систему логирования.

Командой logger можно сохранить сообщение в /var/log/syslog в фоновых скриптах, таких как автозагрузчики.

Да, но у нас уже есть systemd-journald. Нужен ли ещё и rsyslogd?

Rsyslog и Journal, это два приложения протоколирования в системе. У них есть несколько различающихся функций, которые более предпочтительны в той или иной ситуации. В большинстве случаев лучше сочетать возможности обоих, например, для создания структурированных сообщений и сохранения их в файлах. Интерфейс связи для кооперирования предоставляется модулями ввода и вывода Rsyslog и сокетом Journal.

И всё же? На всякий случай, я его оставлю.

/usr/sbin/acpid

acpid — демон для усовершенствованного интерфейса управления конфигурацией и питанием.

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

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

Но у меня виртуальная машина и я не собираюсь отключать устройства. Ради эксперимента я попробую удалить его.

Мне удалось успешно перезагрузить машину при помощи reboot, но после halt, Digital Ocean всё ещё думал, что машина включена и мне пришлось выключить её через веб интерфейс провайдера.

Поэтому, я бы оставил эту службу.

/usr/bin/lxcfs /var/lib/lxcfs/

Lxcfs это своего рода предохраняющая файловая система. В Ubuntu 15.04 она используется по двум причинам: первое, визуализировать некоторые файлы в /proc и второе, ограничить доступ к файловой системе cgroup хоста.

В итоге, можно создавать контейнеры привычным образом с lxc-create и у контейнера будут правильные значения uptime, top, и т.д. Файловая система позволяет контейнеру больше вести себя как отдельная система, нежели без данной файловой системы.

Если не используете контейнеры LXC, то можно удалить с помощью

 

/usr/lib/accountservice/accounts-daemon

AccountsService предоставляет интерфейсы D-Bus для манипуляций с учётными данными пользователей. Использование интерфейсов реализовано в командах usermod(8), useradd(8) и userdel(8).

Когда я удалил D-Bus, это сломало timedatectl. Мне интересно, что сломается, когда я удалю эту службу.

Время покажет.

/sbin/mdadm

mdadm это утилита Linux для администрирования и мониторинга программных RAID устройств.

RAID — технология виртуализации данных, которая объединяет несколько дисков в один логический элемент. У RAID есть 2 основные задачи: 1) увеличения объёма логического диска: RAID 0. Если объединить 2 диска по 500 Гб, то получится 1 Тб. 2) Избежать потерю данных если один из дисков откажет: например, RAID 1, RAID 5, RAID 6, и RAID 10.

Можно удалить с помощью:

 

/usr/lib/policykit-1/polkitd —no-debug

polkit это фреймворк авторизации. Я так понимаю, что это своего рода sudo и он позволяет непривилегированным пользователям выполнять определённые команды от имени администратора, например, перезагружать систему.

Но у меня сервер. Можно удалить с помощью

Мне до сих пор интересно, что из-за него сломается.

/usr/sbin/sshd -D

sshd (OpenSSH Daemon) демон для ssh. С -D он не будет переведен в режим работы демона. Это позволит легче осуществлять мониторинг sshd.

/sbin/iscsid

iscsid это системная служба, запускаемая в фоновом режиме, работающая с конфигурацией iSCSI и управляющая подключениями.

Я никогда не слышал о iSCSI:

iSCSI — протокол, который базируется на TCP/IP и разработан для установления взаимодействия и управления системами хранения данных, серверами и клиентами.

Можно удалить с

 

/sbin/agetty —noclear tty1 linux

agetty — Linux альтернатива getty.

getty это Unix программа, работающая на системах с физическими или виртуальными терминалами. При подключении, она запрашивает имя пользователя и запускает программу login для аутентификации.

Это позволяет войти в систему при физическом доступе к нему. В Digital Ocean, например, можно открыть консоль из браузера и подключиться к этому терминалу (кажется через VNC).

Раньше, можно было наблюдать как несколько терминалов стартовали систему (настроенных в /etc/inittab), но сейчас всё делает systemd.

Ради эксперимента, я удалил файл конфигурации, который запускает и создаёт agetty:

При перезагрузке сервера, я по прежнему мог аутентифицироваться через SSH, но не через веб консоль провайдера.

sshd: root@pts/0, -bash и htop

sshd: root@pts/0 означает, что была установлена SSH сессия для пользователя root в псевдотерминале (pts) №0.

bash это командная оболочка, которую я использую. Но почему перед bash стоит дефис? Пользователь Reddit под ником hirnbrot объяснил:

Там стоит дефис, потому что запуск его как «-bash», активирует login-оболочку. Login-оболочка это такая оболочка, у которой первый символ аргумента под номером 0 дефис, либо он запущен с параметром —login. В результате используются разные файлы настроек.

htop — интерактивная программа для просмотра процессов, которая изображена на скриншоте.

После

 

Крайняя степень:

 

За кадром

 

Исходный код

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

Сперва, надо найти где начать искать.

Тут видно, что uptime находится в /usr/bin/uptime и что в Ubuntu это часть пакета procps.

Затем, можно зайти на packages.ubuntu.com и найти этот пакет.

Страница procps: http://packages.ubuntu.com/source/xenial/procps

Внизу есть ссылки на репозитории с исходными кодами:

 

Дескрипторы файлов и перенаправление

Если нужно перенаправить стандартный поток ошибок (stderr) в стандартный выходной поток, нужно это делать с 2&>1 или 2>&1?

Можно запомнить положение амперсанда пониманием того, что echo нечто > файл запишет нечто в файл файл. Это тоже самое, что echo нечто 1> файл. А вот echo нечто 2> файл запишет поток ошибок в файл.

Если написать echo нечто 2> 1, то поток ошибок перенаправится в файл, с именем 1.

Если поставить перед 1 амперсанд &, то это будет означать, что 1 это не имя файла, а идентификатор потока. Поэтому правильно echo нечто 2>&1.

Цвета в PuTTY

Если некоторые элементы сверху не отображаются при использовании PuTTY, то можно это исправить так.

  1. Нажмите правой кнопкой на заголовок окна
  2. Выберите Change settings
  3. Перейдите в Window → Colours
  4. Отметьте опцию Both
  5. Нажмите Apply

Командная оболочка на C

Попробуем написать очень простую командную оболочку на C, которая бы использовала системные вызовы fork/exec/wait. Программа shell.c:

Скомпилируем программу:

И запустим её:

Вы когда нибудь интересовались почему при запуске программы в фоновом режиме вы видите, что она завершила свою работу, только после нажатия Enter?

Это потому, что оболочка ждёт ввода. Только после ввода команды, оболочка проверяет состояния процессов в фоне и выводит, что они завершились.

https://habrahabr.ru/post/316806/