Skip to content

Заметки по Linux для самых маленьких

License

Notifications You must be signed in to change notification settings

ololobster/linux-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 

Repository files navigation

Заметки по Linux

Оригинал — github.com/ololobster/linux-cli.

  1. Введение: shell и виртуальные консоли, SSH, SSH-прокси, конвейер и потоки, подстановка путей файлов по шаблону
  2. Информация о системе: пользовательские лимиты
  3. ФС: LVM, монтирование
  4. Манипуляции с файлами: rsync и scp, архивы, права, find
  5. Манипуляции с текстом: grep, sed, vim
  6. Сеть: interfaces, NetworkManager, systemd-networkd, curl
  7. Пользователи: sudo и su, локаль
  8. Службы systemd: создание службы, монтирование с systemd
  9. Переменные окружения
  10. Криптография и безопасность: контрольные суммы, gpg, КриптоПро, Astra Linux, пакет ldap-utils
  11. Исполняемые файлы и библиотеки
  12. DEB-пакеты: репозитории
  13. Сборка DEB-пакетов: патчинг c quilt
  14. RPM-пакеты
  15. Сборка RPM-пакетов
  16. Ядро, модули ядра
  17. Разработка: pkg-config, Autotools, CMake, gdb, Python
  18. Скрипты на Bash: функции, блок if, блок case, циклы
  19. Прочее: youtube-dl, манипуляции с документами

Введение

Shell и виртуальные консоли

Shell — это интерпретатор командной строки. Вывести текущий интерпретатор:

$ echo $SHELL

Классификация login/non-login:

  1. Login shell — это shell, который запускается при входе пользователя в систему.
  2. Non-login shell — это shell, который запускается уже находящимся в системе пользователем.

Это можно посмотреть так (если есть чёрточка, то это login shell):

$ echo $0
-bash

Классификация interactive/non-interactive:

  1. Interactive shell — это shell, в котором можно печатать и прерывать выполнение команд.
  2. Non-interactive shell — это shell, который порождается другим процессом.

Первичная консоль (boot console) выводит отладочную информацию при загрузке.

Физический терминал (физическая консоль, teletype ака TTY) — это использовавшееся в древности устройство для ввода команд. Состоит из клавиатуры и монитора. Виртуальная консоль — это ПО, имитирующее физический терминал. У каждой виртуальной консоли есть идентификатор и файл в /dev. Ctrl+Alt+F1 включает виртуальную консоль tty1 и т.д. до tty6; tty7 связан с XServer. Количество активных виртуальных консолей задаётся в /etc/default/console-setup, по умолчанию их 6. При этом /dev/tty0 = /dev/console = текущая консоль, а /dev/tty — это консоль, в которой стартовал процесс.

Псевдо-терминал (pseudo-terminal, PTY) — это пара виртуальных устройств, master (PTM) и slave (PTS). Используется как часть окружения для работы с shell. Псевдо-терминалы создаются для каждого SSH-соединения, для каждой вкладки эмулятора терминала (например, GNOME Terminal или MATE Terminal). PTM создаётся при открытии /dev/ptmx, PTS живут в /dev/pts. Пример:

$ tty
/dev/pts/16
$ echo ololo > /dev/pts/16
ololo

Некоторые сочетания клавиш:

  • очистить экран терминала: Ctrl+L;
  • перейти в начало строки: Ctrl+A;
  • перейти в конец строки: Ctrl+E;
  • удалить слово перед курсором: Alt+Backspace;
  • удалить слово после курсора: Alt+D;
  • если ввести какие-то символы и дважды жмакнуть Tab, то выводится список команд, начинающихся с этих символов.

SSH (Secure Shell)

Подключиться к удалённой ЭВМ по SSH:

$ ssh ⟨user⟩@⟨server⟩

Примечания:

  1. Можно использовать конкретный ключ для аутентификации: -i ⟨private key file⟩. Этот файл должен иметь права 600.

Пробросить порт по SSH:

$ ssh -f -N -L ⟨localhost port⟩:⟨target host⟩:⟨target port⟩ ⟨user⟩@⟨public server⟩

Сгенерировать ключи:

$ ssh-keygen

Теперь публичный ключик в ~/.ssh/id_rsa.pub, приватный — в ~/.ssh/id_rsa.

Чтобы настроить вход на сервер без пароля, клиент выполняет (ключи должны быть сгенерированы):

$ ssh-copy-id ⟨user⟩@⟨host⟩

Примечания:

  1. Это добавит новый публичный ключ в файл ~/.ssh/authorized_keys на сервере.
  2. Если всё равно просит пароль, то на сервере проверяем права authorized_keys (должно быть 600) и родительского каталога (должно быть 700).

Удалить хост из файла known_hosts:

$ ssh-keygen -f ~/.ssh/known_hosts -R ⟨host⟩

Некоторые настройки SSH-сервера (/etc/ssh/sshd_config):

  1. PasswordAuthentication (yes или no) — разрешена ли аутентификация по паролю.
  2. PermitRootLogin (yes, prohibit-password, forced-commands-only или no) — можно ли root'у зайти по SSH. prohibit-password означает, что таки можно, но только по ключу.
  3. AddressFamily, Port и ListenAddress — настройки соединения.

SSH-прокси

Дано:

  • у нас проброшены ключи к public-server;
  • local-server находится в одной локалке с public-server, из вне не доступен.

Задача: подключаться к local-server как обычно, т.е.

$ ssh ⟨local server user⟩@local-server

Решение. В ~/.ssh/config добавить:

Host public-server
    User ⟨public server user⟩
    ForwardAgent yes
    HostName ⟨public server ip⟩
    Port ⟨port⟩

Host local-server
    User ⟨local server user⟩
    HostName ⟨local server ip⟩
    ProxyJump public-server

Конвейер и потоки

Конвейер (pipe) перенаправляет вывод (stdout) 1-й команды на вход (stdin) 2-й команды:

$ ⟨command 1⟩ | ⟨command 2⟩

Примечания:

  1. Все команды в конвейере выполняются параллельно, каждая в своем процессе.
  2. Попытка чтения из пустого буфера блокирует процесс, равно как и попытка записи в заполненный буфер.
  3. Вывод ошибок (stderr) не перенаправляется.
  4. Код завершения конвейера — это код завершения последней команды. Это можно изменить с
    $ set -o pipefail
    

Интересные «устройства»:

  • /dev/stdin — стандартный ввод (файловый дескриптор 0);
  • /dev/stdout — стандартный вывод (файловый дескриптор 1);
  • /dev/stderr — стандартный вывод ошибок (файловый дескриптор 2);
  • /dev/fd/⟨file descriptor⟩ — заданный файловый дескриптор;
  • /dev/null — сюда можно скидывать ненужное.

Пример:

$ echo 'this is stdout' > /dev/fd/1
this is stdout

Писать stdout и stderr в разные файлы:

$ ⟨command⟩ 1> capture.log 2> error.log

Писать stdout и stderr в один файл:

$ ⟨command⟩ > capture.log 2>&1

> перезаписывает файл, а >> добавляет содержимое в конец файла. Альтернатива — tee, которая читает из stdin и пишет в stdout и файлы. По умолчанию файлы перезаписывается, -a ака --append повелевает добавлять содержимое в конец файла.

Подстановка путей файлов по шаблону

Синтаксис шаблонов:

  • asterisk ака wildcart ака * — это любая строка, в т.ч. пустая;
  • ? — это любой символ;
  • [] — любой символ из перечисленных в скобках.

Найденные файлы передаются в программу как аргументы командной строки:

$ echo 'wordpress-*'
wordpress-*
$ echo wordpress-*
wordpress-5.7.6.zip wordpress-5.8.4.zip wordpress-5.8.zip wordpress-5.9.2.zip
$ echo wordpress-5.8??.zip
wordpress-5.8.4.zip
$ echo wordpress-5.[0-9].[0-9].zip
wordpress-5.7.6.zip wordpress-5.8.4.zip wordpress-5.9.2.zip

Если файлов, подходящих под шаблон не нашлось, то программе передаётся 1 аргумент — сам шаблон.

Информация о системе

Вывести информацию по железу:

# dmidecode

Если нужна только мать, то добавляем -t 2, если память — то -t 17.

Также есть:

  • lscpu и lsmem (пакет util-linux);
  • lspci (пакет pciutils);
  • lsusb (пакет usbutils);
  • файлы /proc/cpuinfo и /proc/meminfo.

Вывести температуру CPU (требуется пакет lm-sensors):

$ sensors

Вывести дерево процессов:

$ ps -aux --forest

Запустить процесс, для которого в роли / будет выступать указанный каталог:

$ chroot ⟨root dir⟩ ⟨command⟩

Вывести системную переменную:

$ getconf ⟨var⟩

Некоторые переменные:

  • PAGE_SIZE — это объём страницы памяти в байтах;
  • LONG_BIT, INT_MAX, INT_MIN и т.д.

Найти бинарь, службу или иной системный файл (требуется пакет mlocate):

  1. Один раз:
    # updatedb
    
  2. $ locate ⟨file⟩
    

Вывести load average для 1, 5 и 15 минут (2 варианта):

$ cat /proc/loadavg
$ uptime

Вывести инфу по пространствам имён Linux:

# lsns

Пользовательские лимиты

Вывести все лимиты текущего пользователя:

$ ulimit -a

Чтобы вывести конкретный лимит используем нужный флаг.

Некоторые параметры:

  1. nofile (флаг -n) — максимальное количество открытых файлов.
  2. nproc (флаг -u) — максимальное количество процессов.
  3. stack (флаг -s) — максимальный размер стека в Кб.
  4. fsize (флаг -f) — максимальный размер файла в Кб.
  5. core (флаг -c) — максимальный размер core-файла в Кб.

Для перманентного изменения параметра надо внести его в /etc/security/limits.conf. См. также man limits.conf.

ФС

Initrd (initial RAM disk) — это временная ФС, используемая ядром Linux при начальной загрузке. Initrd обычно используется для начальной инициализации перед монтированием настоящих ФС.

GPT (GUID Partition Table) — это формат размещения таблиц разделов на диске. В отличие от DOS поддерживает объем более 2 Тб.

Вывести свободное место на дисках:

$ df -hT

Примечания: -h — это человекочитаемый формат, -T — это показывать тип ФС.

Вывести статистику по inode:

$ df -i

Узнать размер папки:

$ du -sh ⟨directory⟩

Вывести диски:

$ lsblk

Вывести инфу по диску (указывать диск, например, /dev/sdc):

# hdparm -i ⟨disk device⟩

Выполнить readonly проверку на бэдблоки (указывать раздел, например, /dev/sdc1):

# badblocks ⟨device⟩

Получить UUID всех разделов:

$ ls -l /dev/disk/by-uuid

Проверить диск на битые сектора (указывать раздел, например, /dev/sdc1):

# badblocks -n ⟨device⟩

Отформатировать диск (указывать раздел, например, /dev/sdc1):

# mkfs --type=⟨type⟩ ⟨device⟩

Примечания:

  1. Примеры типов: ext4, vfat.
  2. Раздел не должен быть смонтирован.

Записать загрузочный USB (указывать диск, например, /dev/sdb):

# dd bs=4M if=in.iso of=⟨device⟩ conv=fdatasync

Создать ISO из каталога in:

$ genisoimage -J -joliet-long -r -o out.iso in

Начать работу с parted в интерактивном режиме (указывать диск, например, /dev/sdc):

# parted ⟨disk device⟩

Примечания:

  1. mklabel GPT — выпилить все данные на диске, создать таблицу разделов в формате GPT.
  2. mkpart ⟨label⟩ ext4 2048s 100% — создать раздел с ext4 на весь диск.
  3. p ака print — вывести инфу по выбранному диску.
  4. q ака quit — выйти.
  5. fdisk пока умеет только в таблицу разделов DOS.
  6. Не забываем отформатировать новые разделы.

Чтобы увеличить размер ФС, надо удалить раздел и пересоздать его с новым размером:

# fdisk /dev/vda
p
d
n
p
# resize2fs /dev/vda1

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

Выполнить команду, отключив fsync():

$ eatmydata ⟨command⟩

Найти процессы, использующие файл или папку:

$ lsof | grep ⟨file or directory⟩

Примечания:

  1. -p позволяет задать нужный PID или сразу несколько через запятую. Можно исключать ненужные при помощи ^, например, ^1,^2,^3.
  2. -u позволяет задать нужного пользователя или сразу несколько через запятую. Можно исключать ненужных при помощи ^, например, ^root,^georgiy.

Вывести список процессов, которые используют файлы:

$ lslocks

Примечания:

  1. -p ака --pid позволяет задать нужный процесс.
  2. Если процесс заблокирован из-за того, что файл уже используется, то в колонке MODE будет *.

Монтирование

Монтировать диск (точка монтирования должна существовать):

# mount -t ⟨type⟩ -o ⟨options⟩ ⟨device⟩ ⟨mount point⟩

Монтировать ISO:

# mount -o loop in.iso ⟨mount point⟩

Чтобы диск монтировался автоматом, надо добавить соответствующую запись в /etc/fstab:

⟨device⟩ ⟨mount point⟩ ⟨type⟩ ⟨options⟩ ⟨dump⟩ ⟨pass⟩

Пример:

/dev/vdb1 /data ext4 rw 0 1

Примечание: после изменения /etc/fstab можно, не перезагружая ЭВМ, сделать:

# mount ⟨mount point⟩

Создать раздел на tmpfs:

# mount -t tmpfs -o rw,size=2G tmpfs ⟨mount point⟩

Через /etc/fstab:

tmpfs ⟨mount point⟩ tmpfs rw,size=2G 0 0

Монтировать папку, находящуюся на другой ЭВМ, по SSH:

$ sshfs ⟨user⟩@⟨host⟩:⟨directory⟩ ⟨mount point⟩

LVM (logical volume management)

Warning: если сдохнет один из HDD, управляемых LVM, то можно потерять все данные.

Вывести инфу по группам томов:

# vgdisplay

Вывести инфу по томам:

# lvdisplay

Создать группу томов:

# vgcreate -c n ⟨group name⟩ ⟨partion device 1⟩ ... ⟨partion device N⟩

Примечания:

  1. Есть флаг --yes.

Создать том, занимающий 100% объёма своей группы:

# lvcreate -l 100%VG -n ⟨volume name⟩ ⟨group name⟩

Примечания:

  1. -l ака --extents также позволяет указать % от свободного места, например, -l 100%FREE.
  2. -L ака --size позволяет указать точный размер, например, -L 10g.
  3. Теперь надо отформатировать /dev/⟨group name⟩/⟨volume name⟩ и можно монтировать.

Расширить том:

  1. Убедиться, что в группе есть свободное место.
  2. Расширить том:
    # lvextend -l +⟨PE⟩ ⟨volume path⟩
    
    Количество доступных PE (physical extents) можно посмотреть в свойствах группы.
  3. Расширить ФС. Например, для ext4:
    # resize2fs ⟨volume path⟩
    

Манипуляции с файлами

Эти 2 команды аналогичны:

$ cp /home/sample.txt{,-old}
$ cp /home/sample.txt /home/sample.txt-old

Пакет rename для пакетного переименования файлов:

$ rename 's/⟨было⟩/⟨стало⟩/' *.txt

Создать символьную ссылку:

$ ln -s ⟨путь к источнику⟩ ⟨путь к ссылке⟩

Здесь -s — это символьная ссылка (по умолчанию — жесткая ссылка), -f разрешает удаление существующих файлов.

Получить из пути имя файла/папки:

$ basename ⟨path⟩

Получить из пути путь родительской папки:

$ dirname ⟨path⟩

Удалить файл с многократной перезаписью случайными данными:

$ shred -u -z -n 40 ⟨file 1⟩ ⟨file 2⟩ ...

Примечания:

  1. -n ака --iterations позволяет задать количество проходов.
  2. -z ака --zero указывает выполнить финальный проход с заполнением нулями.
  3. -u указывает удалить файл в конце.

rsync и scp

Копировать с rsync:

$ rsync ⟨source⟩ ⟨target directory⟩

Примечания:

  1. Можно качать по SSH — ⟨user⟩@⟨host⟩:⟨path⟩. При этом rsync должен быть установлен и на удалённой машине.
  2. Если надо копировать содержимое каталога, то добавляем / в конце пути. Если надо копировать сам каталог, то не добавляем.
  3. -r ака --recursive — рекурсивно копировать папку.
  4. -l ака --links — копировать символьные ссылки как символьные ссылки.
  5. -e ака --rsh позволяет задать shell. Например, задаём нестандартный порт: --rsh='ssh -p 222'.
  6. --exclude позволяет игнорировать ненужные файлы, причём аргументов --exclude может быть несколько. Пример: --exclude=*.pdf.

Копировать с scp:

$ scp ⟨source⟩ ⟨target directory⟩

Примечания:

  1. Можно качать по SSH — ⟨user⟩@⟨host⟩:⟨path⟩.
  2. -r — рекурсивно копировать папку.
  3. Если надо указать порт, то используем -P.
  4. scp не умеет нормально выкачивать символьные ссылки.

Архивы

Распаковать tar.gz:

$ tar -xf in.tar.gz

Вынуть один файл из tar.gz:

$ tar -zxf in.tar.gz ⟨file to extract⟩

Примечание: --directory ака -C задаёт каталог для записи.

Вывести список файлов, запакованных в tar.gz:

$ tar -ztf in.tar.gz

Запаковать файл или каталог в tar.gz:

$ tar -zcf out.tar.gz ⟨file or directory⟩

Запаковать всё содержимое текущего каталога в tar.gz:

$ tar -zcvf out.tar.gz .

Примечания:

  1. Можно указать сразу много файлов и каталогов.
  2. tar нормально пакует символьные ссылки.

Запаковать и отправить по SSH без создания файла на локальной ЭВМ:

$ tar -zcvf - --one-file-system ⟨file or directory⟩ | ssh ⟨login⟩@⟨host⟩ "cat > ⟨new tar.gz file⟩"

Распаковать zip (2 способа):

$ unzip in.zip
$ 7z x in.zip

Запаковать каталог в zip:

$ zip -r out.zip ⟨directory⟩

Можно указывать сразу много файлов и папок. Для файлов -r не нужен.

Распаковать rar:

$ unrar e in.rar

Запаковать файл или папку в rar:

$ rar a out.rar ⟨file or directory⟩

Можно указать сразу много файлов и папок. Чтобы поставить пароль на архив используем -p.

Распаковать xz (нужен пакет xz-utils):

$ unxz in.xz

Права

Обозначение Права
0 ---
1 --x
2 -w-
3 -wx
4 r--
5 r-x
6 rw-
7 rwx

1777 (отображается как drwxrwxrwt) — это спец. права: всем всё можно, но удалять может лишь тот кто создал.

Изменить права на файл или папку:

$ chmod ⟨permissions⟩ ⟨file or directory⟩

Здесь permissions — это права владельца файла, группы файла и всех остальных, например, 664. Для рекурсивной обработки подкаталогов используем -R или --recursive.

Сменить владельца для файла или папки:

$ chown ⟨user⟩ ⟨file or directory⟩

Сменить владельца и группу для файла или папки:

$ chown ⟨user⟩:⟨group⟩ ⟨file or directory⟩

-R ака --recursive — рекурсивно обработать содержимое папки.

Сменить группу для файла или папки:

$ chgrp ⟨group⟩ ⟨file or directory⟩

-R ака --recursive — рекурсивно обработать содержимое папки.

Запретить изменение:

# chattr +i ⟨file or directory⟩

Вывести правила ACL (Access Control Lists ака списки управления доступом) для файла или каталога:

$ getfacl ⟨path⟩

Создать правило ACL для пользователя/группы:

$ setfacl -m u:⟨user⟩:rwx ⟨path⟩
$ setfacl -m g:⟨group⟩:rwx ⟨path⟩

Примечания:

  1. -R повелевает применить изменения рекурсивно.
  2. Комбинация -d -m указывает, что создаётся правило по умолчанию (Default ACL) для каталога. Это правило будет применяться к создаваемым там файлам.
  3. Для полного запрета указываем права 0.

find

Поиск больших логов:

$ find /var/www -type f -name 'access.log*' -size +100M

Поиск всех файлов в каталоге /etc/, измененных за последние сутки:

$ find /etc/ -type f -mtime -1

Подсчитаем суммарный объём логов:

$ find /var/www/ -type f -name 'access.log*' -exec du -k {} \; | awk '{s+=$1}END{print s}'

Манипуляции с текстом

Вывести количество строк:

$ cat ⟨file⟩ | wc -l

Вывести количество слов:

$ cat ⟨file⟩ | wc -w

Вывести количество символов:

$ cat ⟨file⟩ | wc -m

Разрезать строку по символу-разделителю:

$ echo '12.11.70.19~rc1' | cut -d '~' -f 1
12.11.70.19

Распарсить JSON:

$ echo '{"a": 1, "b": 2}' | jq .b
2

Подставить в строку переменные:

$ echo 'login=${LOGNAME}' | envsubst

Сравнение папок при помощи пакета diffoscope:

$ diffoscope --html=log.html --exclude-directory-metadata=yes --max-page-size=15000000 --max-page-diff-block-lines=5000 --no-default-limits ⟨path 1⟩ ⟨path 2⟩

--exclude=⟨pattern⟩ позволяет игнорировать ненужные файлы, причём аргументов --exclude может быть несколько.

Выполнить XSLT-преобразование:

$ xalan -xsl in.xsl -in in.xml -out out.xml

xsltproc — это глючная дрянь, не работают ни xalan:indent-amount ни saxon:indent-spaces.

Преобразовать файл в HEX и вывести в stdout:

$ xxd ⟨input file⟩

grep

Вывести строки, включающие паттерн ⟨pattern⟩:

$ ⟨command⟩ | grep ⟨pattern⟩

Вывести строки, удовлетворяющие регулярке ⟨pattern⟩:

$ ⟨command⟩ | grep -e '⟨pattern⟩'

Вывести строки, которые не включают паттерн ⟨pattern⟩:

$ ⟨command⟩ | grep -v ⟨pattern⟩

Примечания:

  1. Флаг --ignore-case ака -i повелевает игнорировать регистр. По умолчанию учитывается.
  2. --max-count ака -m позволяет ограничить количество результаов.
  3. Оператор ИЛИ в шаблоне: samba\|smbd.
  4. Выводить также N строк перед найденной строкой: -B ⟨N⟩.
  5. Выводить также N строк после найденной строки: -A ⟨N⟩.

Проверить наличие строки в файле:

$ grep --quiet ⟨pattern⟩ ⟨path⟩

Примечание: если есть — вернёт 0, нет — вернёт 1.

sed

Внести изменения в файл:

$ sed -i ⟨action⟩ ⟨file⟩

Примечания:

  1. Если не указать файл, то sed будет читать из stdin.
  2. -i ака --in-place повелевает перезаписать файл (по умолчанию пишет в stdout).
  3. При помощи ; можно применить несколько действий за раз:
    $ echo 'abcd' | sed 's/ab/xy/; s/cd/ab/; s/xy/cd/'
    cdab
    

Примеры действий:

  • s/before/after/g — везде заменить «before» на «after»;
  • s/\r//g — избавиться от символа \r;
  • 1,3s/before/after/g — заменить «before» на «after» в строках с 1 по 3;
  • 1,3s/^/prefix/ — добавить префикс в строки с 1 по 3;
  • 1,3s/$/postfix/ — добавить постфикс в строки с 1 по 3;
  • /pattern/s/before/after/g — заменить «before» на «after» в строках, которые содержат «pattern»;
  • 1,3d — удалить строки с 1 по 3;
  • /pattern/d — удалить строки, которые содержат «pattern»;
  • /^$/d — удалить пустые строки;
  • /pattern/!d — удалить строки, которые не содержат «pattern»;
  • 3c\new line — заменить 3-ю строку на «new line»;
  • /pattern/c\new line — заменить строки, которые содержат «pattern», на «new line»;
  • 1i\new line — вставить новую строку перед 1-й строкой (т.е. в самое начало);
  • 1a\new line — вставить новую строку после 1-й строки.

Примечания:

  1. Указание строк, к которым следует применить действие:
    • 1 — самая 1-я строка;
    • 1,3 — строки с 1-й по 3-ю включительно;
    • 3,$ — все строки начиная с 3-й.
  2. Без флажка g будет производиться лишь 1 замена в каждой строке (1-е вхождение). Вместо g можно указать номер вхождения, например, s/before/after/2 заменит 2-е вхождение «before» в каждой строке.
  3. Если / неудобен в качестве разделителя, то можно использовать другой символ. Пример: s!/usr/lib!/usr/share!g.

Вывести всё, что находится между строкой, содержащей «pattern1», и строкой, содержащей «pattern2», включая сами эти строки:

$ sed -n '/pattern1/,/pattern2/p' ⟨file⟩

Аналогично, но не включая эти строки:

$ sed -n '/pattern1/,/pattern2/{{//!p}}' ⟨file⟩

vim

Команды vim:

  1. :w — сохранить.
  2. :q — выйти из vim.
  3. :wq — выйти из vim с сохранением.
  4. :q! — выйти из vim без сохранения.
  5. :set number ака :set nu — отображать номера строк.
  6. :set nonumber ака :set nu! — не отображать номера строк.
  7. i — войти в режим вставки.
  8. Escape — выйти из режима вставки.
  9. dd — удалить строку.
  10. /⟨search term⟩ — искать. n — следующий, N — предыдущий.
  11. u ака :u ака :undo — отмена.

Вырезать и вставлять текст:

  1. V, чтобы выбрать нужные стороки (или v чтобы выбрать кусочек стороки).
  2. d, чтобы вырезать.
  3. p, чтобы вставить после курсора.

Сеть

Вывести информацию об интерфейсе (нужен пакет ethtool):

# ethtool ⟨interface⟩

Примечания: можно смотреть воткнут ли кабель в разъём.

Отключить интерфейс:

# ifconfig ⟨interface⟩ down

Удалить виртуальный интерфейс:

# ip link delete ⟨interface⟩

Вывести драйвер, используемый интерфейсом:

$ readlink -f /sys/class/net/⟨interface⟩/device/driver

Вывести открытые локальные порты (нужен пакет net-tools):

$ netstat -tulpn

Чтобы показывало процессы, нужны права root.

Вывести количество соединений (нужен пакет net-tools):

$ netstat -an | wc -l

Убить процесс, висящий на заданном порте:

$ fuser -k ⟨port⟩/tcp

Вевести список ЭВМ в заданной сети:

$ nmap -sP 192.168.50.0/24

Проверить открыт ли конкретный порт на конкретной ЭВМ:

$ nmap ⟨host⟩ -p ⟨port⟩

Добавить/удалить маршрут:

# route add -net 10.1.1.0/24 gw 10.10.0.1
# route del -net 10.1.1.0/24 gw 10.10.0.1

Вывести правила брандмауэра netfilter:

# iptables --list

Разрешить весь исходящий трафик:

# iptables -P OUTPUT ACCEPT

Записать трафик tcpdump'ом для wireshark:

# tcpdump -i ⟨interface⟩ -s 65535 -w ⟨file⟩

Отлавливать обмен пакетами с заданным узлом:

# tcpdump host ⟨ip⟩

traceroute определяет маршрут следования данных в сетях TCP/IP:

$ traceroute ⟨host⟩

Для определения промежуточных маршрутизаторов traceroute шлёт целевому узлу пакеты (по умолчанию UDP), с каждым шагом увеличивая значение поля TTL на 1. 1-й маршрутизатор получает пакет с TTL = 1 и сообщает об ошибке. Процесс повторяется до тех пор, пока пакет не достигнет целевого узла.

Настройка интерфейсов с /etc/network/interfaces

Пример интерфейса с DHCP:

auto eth0
iface eth0 inet dhcp

Пример интерфейса со статическим адресом:

auto eth0
iface eth0 inet static
    address 10.1.12.21
    netmask 255.255.255.0
    gateway 10.1.0.1

Если не задать netmask, то система не выдаст ошибку, а попробует подобрать маску самостоятельно. Но делать так НЕ надо, надо задавать.

NetworkManager

Вывести список устройств/соединений:

$ nmcli device status
$ nmcli connection show

NetworkManager не будет управлять устройствами, которые настраиваются через /etc/network/interfaces. Также можно задать игнорируемые устройства в конфиге. Пример:

$ cat /etc/NetworkManager/conf.d/99-unmanaged-devices.conf
[keyfile]
unmanaged-devices=interface-name:eth1;interface-name:eth2

Настройка интерфейсов с systemd-networkd

Правило представляет собой файл с расширением .network или .link, лежащий в /etc/systemd/network. Пример: 10-persistent-net.link.

Задать название интерфейса (требуется расширение .link):

[Match]
MACAddress=⟨mac⟩

[Link]
Name=⟨name⟩

Примечания:

  1. Если уж назначать имена, то всем, иначе возможны глюки с появлением интерфейсов типа rename5.
  2. Systemd написан через жопу и может просто не функционировать как описано в документации. Если от проблем с rename5 не удаётся избавиться, то см. баг 1390.

Пример интерфейса с DHCP (тут и далее требуется расширение .network):

[Match]
Name=⟨interface⟩

[Network]
DHCP=yes

Пример интерфейса со статическим адресом:

[Match]
Name=⟨interface⟩

[Network]
Address=⟨IP⟩/⟨mask⟩
Gateway=⟨gateway⟩
DNS=⟨DNS server⟩

Просим systemd-networkd не трогать интерфейс (хотим настраивать посредством /etc/network/interfaces):

[Match]
Name=⟨interface⟩

[Link]
Unmanaged=yes

А ещё можно использовать *, например, Name=en*.

curl

Закачать что-нибудь:

$ curl --output ⟨path⟩ ⟨url⟩

Примечания:

  1. --output ака -o — это именно новый файл, НЕ каталог. В качестве альтернативы есть --remote-name ака -O (оставить оригинальное имя файла) и --output-dir (по умолчанию текущий каталог).

Вывести HTTP-заголовки:

$ curl --head ⟨url⟩

Отправить простой POST-запрос (application/x-www-form-urlencoded):

$ curl -d 'email=test@test.com&password=test' -X POST ⟨url⟩

Отправить простой POST-запрос с данными из локального файла in.txt:

$ curl -d '@in.txt' -X POST ⟨url⟩

Отправить POST-запрос с JSON:

$ curl -d '{"test":1}' -H 'Content-Type: application/json' -X POST ⟨url⟩

Примечания:

  1. Для бинарных данных следует использовать не --data ака -d, а --data-binary.

DNS

Используемые DNS-сервера прописаны в /etc/resolv.conf.

Получить DNS-записи для доменного имени (нужен пакет dnsutils):

$ dig ⟨domain name⟩

Пользователи

Создать пользователя и задать ему пароль:

# useradd --create-home --shell /bin/bash ⟨user⟩
# passwd ⟨user⟩

Вывести группы, в которых состоит пользователь:

$ groups ⟨user⟩

Примечание: если пользователь не указан, то свои группы.

Добавить пользователя в группу:

# usermod -aG ⟨group⟩ ⟨user⟩

Чтобы изменения вступили в силу, пользователю надо перелогиниться.

Вывести всех залогиненых пользователей:

$ who

sudo и su

Стать другим пользователем:

su ⟨user⟩

При этом потребуется ввести пароль этого пользователя. Флаг -p позволяет оставить свои переменные окружения.

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

sudo ⟨command⟩

При этом, возможно, потребуется ввести собственный пароль. Флаг -E ака --preserve-env позволяет оставить свои переменные окружения.

Право использовать sudo выдаётся через /etc/sudoers:

  • разрешить использовать sudo, спрашивать пароль:
    ⟨user⟩ ALL=(ALL:ALL) ALL
    
  • разрешить использовать sudo, не спрашивать пароль:
    ⟨user⟩ ALL=(ALL) NOPASSWD:ALL
    

При правке /etc/sudoers руками, всегда следует использовать visudo.

Локаль

Для того, чтобы сменить локаль, обычно достаточно задать переменную окружения LANG. Например, en_US.UTF-8 повелевает использовать американскую разновидность (US) английского языка (en), и писать в консоль в кодировке UTF-8. Для России используем ru_RU.UTF-8.

Вывести текущую локаль:

$ locale

Вывести список доступных в системе (сгенериррованных) локалей:

$ locale -a

Запустить интерактивный генератор локалей:

# dpkg-reconfigure locales

Установить часовой пояс:

# timedatectl set-timezone 'Europe/Moscow'

Вывести список доступных шрифтов:

$ fc-list

Обновить кеш шрифтов:

$ fc-cache -f -v

Примечение: можно кидать шрифты в ~/.local/share/fonts.

Службы systemd

Где лежат конфиги сервисов:

  • /usr/lib/systemd/user;
  • /run/systemd/system;
  • /etc/systemd/system.

Перезагрузить конфиги сервисов:

# systemctl daemon-reload

Получить статистику запуска сервисов:

$ systemd-analyze plot > out.svg

Создание службы

Типы служб:

  1. simple — главный процесс и является службой.
  2. forking — процесс порождает дочерний процесс и выходит. Systemd считает службу запущенной, хоть процесс и завершился.
  3. oneshot — процесс будет короткоживущим. Systemd ждёт его завершения прежде чем запускать зависимые от него службы.
  4. notify — служба выпустит оповещение, когда она будет готова. Systemd ждёт оповещения прежде чем запускать зависимые от неё службы.
  5. idle — Systemd отложит запуск процесса до момента выполнения всех остальных задач, в остальном аналог simple.
  6. dbus — служба считается запущенной, когда её имя появится в системной шине DBus.

Минимальный пример service-файла:

[Unit]
Description=⟨description⟩

[Service]
Type=simple
ExecStart=⟨command⟩

[Install]
WantedBy=multi-user.target

Примечания по секции Unit:

  1. Before и After — нужно запускать до/после какого-либо сервиса.
  2. Requires — зависимость. Если при старте происходит взаимодействие с другим сервисом, то его надо прописать и в Requires и в After. Если задан лишь Requires, то оба будут запущены одновременно.
  3. BindsTo — то же что и Requires + наш сервис будет остановлен при остановке зависимости.
  4. Wants — слабая версия Requires. Наш сервис будет выполняться, даже если systemd не сумеет запустить эту зависимость.
  5. Conflicts — какой-либо сервис, одновременная работа с которым невозможна.
  6. Любой из параметров Before, After, Requires, BindsTo, Wants, Conflicts может встречаться по несколько раз.
  7. Можно задать условия запуска: AssertPathExists, AssertPathIsReadWrite, AssertDirectoryNotEmpty, AssertFirstBoot и т.д.

Примечания по секции Service:

  1. ExecStart, ExecReload, ExecRestart, ExecStop — команды для запуска, релоада, перезапуска и остановки службы.
  2. ExecStartPre и ExecStartPost — доп. команды, выполняемые до и после ExecStart, например, чтобы создать папку под pid-файл в /var/run. При этом ExecStartPost является частью процедуры запуска; пока он не отработает зависимые службы не запускаются.
  3. ExecStopPost — доп. команда, выполняемая после остановки службы.
  4. В ExecStart и ко надо использовать абсолютные пути, например, /bin/mountpoint.
  5. WorkingDirectory — рабочая папка.
  6. EnvironmentFile — путь к файлу с переменными окружения (обычно в /etc/default).
  7. TimeoutStartSec — таймаут на старт службы, TimeoutStopSec — таймаут на остановку службы, TimeoutSec — единое значение для обоих таймаутов.

Примечания по секции Install:

  1. Если секции нет, то нельзя выполнить systemctl enable. Т.е. если служба не самостоятельна, а является лишь зависимость для других служб, то секция не нужна.
  2. Доступные цели: poweroff.target (runlevel0) — выключение, rescue.target (runlevel1) — rescue shell готов, multi-user.target (runlevel2, 3, 4) — пользователи могут логиниться и использовать CLI, graphical.target (runlevel5) — пользователи могут использовать графический режим, reboot.target (runlevel6) — перезагрузка.

Монтирование с systemd

Пример mount-файла для тома Gluster:

[Unit]
Description=⟨description⟩
BindsTo=glusterd.service
After=glusterd.service

[Mount]
What=localhost:/⟨volume⟩
Where=⟨mount point⟩
Type=glusterfs
Options=defaults,_netdev
DirectoryMode=0755

Примечания:

  1. Имя mount-файла должно соответствовать точке монтирования. Например, /var/lockvolvar-lockvol.mount.
  2. Команда systemctl start монтирует, systemctl stop — отмонтирует.
  3. ExecStartPre и ко недоступны.
  4. При работе с Gluster может понадобиться обеспечить задержку для корректного монтирования.

Переменные окружения

Вывести все переменные окружения:

$ printenv

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

$ ⟨var1⟩=⟨value1⟩ ⟨var2⟩=⟨value2⟩ ⟨command⟩

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

$ i=1 echo "$i"

Так сработает:

$ i=1 bash -c 'echo "$i"'

Локальные переменные (для текущей сессии) задаются и удаляются так:

$ export ⟨var⟩=⟨value⟩
$ unset ⟨var⟩

Переменные для конкретного пользователя лежат в

  1. ~/.bashrc — выполняется при старте нового процесса Bash пользователем, который уже находится в системе (non-login shell).
  2. ~/.bash_profile (или ~/.profile) — выполняется при старте нового процесса Bash, когда пользователь входит по SSH (login shell).

Переменные для всех пользователей лежат в

  1. /etc/bash.bashrc — то же, что и ~/.bashrc, но для всех пользователей (только Debian и Ubuntu).
  2. /etc/profile — то же, что и ~/.bash_profile, но для пользователей.
  3. /etc/environment — тут лежат общесистемные переменные окружения, это не скрипт. Чтобы изменения вступили в силу надо перелогиниться.

Получить значение переменной, а если переменной нет, то использовать значение по умолчанию:

$ echo ${⟨var⟩:-⟨default value⟩}

Создать alias можно, добавив строку в ~/.bashrc или в ~/.bash_aliases (если таковой подключается в ~/.bashrc):

alias ⟨alias⟩=⟨command⟩

Пример:

alias grep='grep --color=auto'

Криптография и безопасность

Расшифровать сообщение в формате ASN.1 DER:

$ openssl asn1parse -inform der -in ⟨file⟩

Вывести сертификаты в указанной БД:

$ certutil -L -d ~/.mozilla/firefox/*.default

Вывести информацию о сертификате в виде файла in.crt:

$ openssl x509 -noout -text -in in.crt

Создать сертификат и ключи в виде PFX-файла (формат PKCS #12):

$ openssl genrsa -des3 -out myCA.key 2048
$ openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
$ openssl pkcs12 -inkey myCA.key -in myCA.pem -export -out out.pfx

Поучить билет Kerberos:

$ kinit -f ⟨user⟩

Вывести билеты Kerberos:

$ klist

Контрольные суммы

MD5 строки:

$ echo -n ⟨string⟩ | md5sum

MD5 файла:

$ md5sum ⟨file⟩

sha1sum, sha256sum, sha512sum — аналогично.

Кодировать строку в base64:

$ echo ⟨string⟩ | base64

Декодировать из base64:

$ echo ⟨base64 string⟩ | base64 -d

Вывести CRC для файла:

$ cksum ⟨file⟩

gpg

Вывести список ключей:

$ gpg --list-keys

Создать ключ:

$ gpg --full-generate-key

Экспортировать публичный ключ в виде key-файла:

$ gpg --armor --output ⟨output key file⟩ --export ⟨id⟩

Создать ЭП для файла in.txt:

$ gpg --output out.sig --sign in.txt

Примечания:

  1. ЭП создаётся при помощи приватного ключа подписанта, а проверяется она при помощи соответствующего публичного ключа.
  2. SIG-файл содержит исходный подписанный файл, при этом он не зашифрован.

Проверить ЭП в файле in.sig:

$ gpg --verify in.sig

Проверить ЭП и вытащить подписанный файл:

$ gpg --output out.txt --decrypt in.sig

Создать отсоединённую ЭП для файла in.txt:

$ gpg --output out.sig --detach-sig in.txt

Проверить отсоединённую ЭП в файле in.sig:

$ gpg --verify in.sig in.txt

Зашифровать файл in.txt:

$ gpg --output out.gpg --encrypt --recipient ⟨id⟩ in.txt

Примечания:

  1. Чтобы зашифровать сообщение Алисе, используется её публичный ключ, а расшировывать она будет своим приватным ключом.
  2. Для расшифровки использовать --decrypt (см. выше).

КриптоПро

Сертификаты и ключи живут в контейнерах, контейнеры живут на носителях.

Вывести список носителей:

$ /opt/cprocsp/bin/amd64/csptest -enum -info -type PP_ENUMREADERS -flags 32

Вывести список контейнеров:

$ /opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -fqcn -verifyc

Вывести сертификаты в uMy (личном хранилище) и mRoot (корневом хранилище):

$ /opt/cprocsp/bin/amd64/certmgr -list -store uMy
$ /opt/cprocsp/bin/amd64/certmgr -list -store mRoot

Импортировать сертификат и ключ (в виде PFX-файла) в личное хранилище:

$ /opt/cprocsp/bin/amd64/certmgr -install -store uMy -pfx -file in.pfx -pin ⟨password⟩

Импортировать сертификат в корневое хранилище:

# /opt/cprocsp/bin/amd64/certmgr -install -store mRoot -file in.cer

Импортировать CRL в личное хранилище:

$ /opt/cprocsp/bin/amd64/certmgr -install -store uCA -crl -file in.crl

Удалить сертификат из хранилища по отпечатку:

$ /opt/cprocsp/bin/amd64/certmgr -delete -store ⟨store⟩ -thumbprint ⟨sha1⟩

Экспортировать сертификат без ключа (в виде CER-файла):

$ /opt/cprocsp/bin/amd64/certmgr -export -certificate -thumbprint ⟨sha1⟩ -dest out.cer

Экспортировать сертификат с ключом (в виде PFX-файла):

$ /opt/cprocsp/bin/amd64/certmgr -export -pfx -thumbprint ⟨sha1⟩ -dest out.pfx

Примечание: опционально -pin ⟨password⟩.

Создать отсоединённую ЭП для файла in.pdf (форматы CAdES-BES, CAdES-X Long Type 1 и CAdES-T):

$ /opt/cprocsp/bin/amd64/cryptcp -sign -thumbprint ⟨sha1⟩ -der -detached -addchain in.pdf out.sig
$ /opt/cprocsp/bin/amd64/cryptcp -sign -thumbprint ⟨sha1⟩ -der -detached -addchain -xlongtype1 -cadesTSA ⟨TSP server⟩ in.pdf out.sig
$ /opt/cprocsp/bin/amd64/cryptcp -sign -thumbprint ⟨sha1⟩ -der -detached -addchain -cadest -cadesTSA ⟨TSP server⟩ in.pdf out.sig

Проверить отсоединённую ЭП in.sig:

$ /opt/cprocsp/bin/amd64/cryptcp -verify -detach in.pdf in.sig -verall

Проверить работоспособность TSP-службы:

$ /opt/cprocsp/bin/amd64/tsputil ms -u ⟨TSP server⟩ --cert-req -a 1.2.643.7.1.1.2.2 in.txt out.tsr

Проверить работоспособность OCSP-службы:

$ /opt/cprocsp/bin/amd64/ocsputil makeresp -u ⟨OCSP server⟩ in.cer

Вывести конкретную групповую политику:

$ /opt/cprocsp/sbin/amd64/cpconfig -ini '\config\cades\ocsppolicy\DefaultOCSPURL' -view

Задать групповую политику:

# /opt/cprocsp/sbin/amd64/cpconfig -ini '\config\cades\ocsppolicy' -add string DefaultOCSPURL http://xxx.ru/ocsp.srf

Вывести инфу по лицензиям КриптоПро:

$ /opt/cprocsp/sbin/amd64/cpconfig -license -view
$ /opt/cprocsp/bin/amd64/tsputil license
$ /opt/cprocsp/bin/amd64/ocsputil license

Вывести инфу по КриптоПро:

$ /opt/cprocsp/bin/amd64/csptestf -enum -info

Astra Linux

Мандатная метка = метка безопасности = уровень конфиденциальности + набор категорий + уровень целостности. Классификационная метка = метка конфиденциальности = уровень конфиденциальности + набор категорий. Набор категорий хранится как число (битовая маска).

На БД и таблицы PostgreSQL, а также на IP-пакеты ляпаются классификационные метки (т.е. без уровня целостности).

Правила доступа:

  1. Субъект может изменять объект, если Lₛ = Lₒ, Cₛ = Cₒ, iLₛ ≥ iLₒ (уровни конфиденциальности и набор категорий совпадают, а уровень целостности субъекта не ниже чем у объекта).
  2. Субъект может читать объект, если Lₛ ≥ Lₒ, Cₒ ⊂ Cₛ. Уровни целостности не имеют значения.

Правила присвоения мандатных меток:

  1. Созданный субъект (например, дочерний процесс) наследует мандатную метку родительского субъекта.
  2. Созданный объект (например, файл) наследует классификационную метку родительского субъекта, а уровень целостности у него будет нулевой.
  3. Мандатная метка объекта-контейнера (например, каталога) определяет макс. мандатную метку его дочерних объектов.

Вывести мандатную метку текущей сессии:

$ pdp-id

Вывести мин. и макс. возможную мандатную метку пользователя:

# pdpl-user ⟨user⟩

Установить для пользователя допустимые уровни конфиденциальности:

# pdpl-user -l ⟨min level⟩:⟨max level⟩ ⟨user⟩

Установить для пользователя максимальный уровень целостности:

# pdpl-user -i ⟨max int level⟩ ⟨user⟩

Примечания:

  1. Эти ограничения для локального пользователя хранятся в /etc/parsec/macdb/⟨uid⟩.

Вывести доступные уровни конфиденциальности:

$ cat /etc/parsec/mac_levels

Вывести доступные категории:

$ /etc/parsec/mac_categories

Вывести макс. возможный уровень целостности:

$ cat /sys/module/parsec/parameters/max_ilev

Вывести мандатную метку процесса:

# pdpl-ps ⟨pid⟩

Вывести все доступные PARSEC-привилегии:

# usercaps -M

Вывести PARSEC-привилегии пользователя:

# usercaps -M ⟨user⟩

Вывести PARSEC-привилегии процесса:

# pscaps ⟨pid⟩

ФС в AstraLinux

Флаги:

  • ccnr — контейнер может содержать сущности с различными классификационными метками, но не большими, чем его собственная;
  • ccnri — игнорировать уровень целостности каталога при просмотре его содержимого;
  • ehole — игнорировать мандатный уровень и категории при выполнении операций записи;
  • CCNRA = ccnr + ccnri;
  • ALL = ccnr + ccnri + ehole.

Вывести список файлов и каталогов с их мандатными метками:

$ pdp-ls -M ⟨path⟩

Изменить мандатную метку файла или каталога:

# pdpl-file ⟨уровень⟩ ⟨path⟩
# pdpl-file ⟨уровень⟩:⟨уровень целостности⟩:⟨категории⟩:⟨флаги⟩ ⟨path⟩

Примечания:

  1. Флаги перечисляются через запятую.
  2. -R для рекурсивного изменения сверху вниз (начиная с родительского каталога). -R -r для рекурсивного изменения снизу вверх.

ALD (Astra Linux Directory)

Домен безопасности (security domain) – это часть автоматизированной системы, которая использует одни и те же политики безопасности. ALD – это одна из реализаций домена безопасности. ALD является надстройкой над технологиями LDAP, Kerberos, CIFS. ЕПП (единое пространство пользователей) – это домен безопасности, работающий на ALD.

Вывести инфу по ЕПП:

# ald-admin status

Добавить категорию:

# ald-admin maccat-add 0x4 cat3

Пакет ldap-utils

Выполнить LDAP-запрос:

$ ldapsearch -H ldap://⟨host⟩ -LLL -Q -o ldif-wrap=no -b ⟨DN⟩ ⟨filter⟩

Примечания:

  1. -Q — использовать SASL-аутентификацию + тихий режим. Работает, если есть активный билет Kerberos.
  2. -LLL — вывести результат в формате LDIF без комментариев и версии.
  3. -S — атрибут, по которому происходит сортировка. Пустая строка означает сортировку по DN.
  4. -s — область поиска (scope): base, one, sub или children.

Получить доступные механизмы SASL-аутентификации:

$ ldapsearch -H ldap://⟨host⟩ -x -LLL -s base -b "" supportedSASLMechanisms

Добавить записи в службу каталогов:

$ ldapadd -Q -H ldap://⟨host⟩ -f ⟨LDIF file⟩

Удалить запись из службы каталогов:

$ ldapdelete -Q -H ldap://⟨host⟩ ⟨DN⟩

Примечания:

  1. Может работать с LDIF-файлами как ldapadd.

Исполняемые файлы и библиотеки

Переменная окружения LD_LIBRARY_PATH — это список каталогов, где ОС ищет динамические библиотеки, прежде чем обратиться к стандартным каталогам, заданным в /etc/ld.so.conf. Для Qt-приложений также есть QT_PLUGIN_PATH.

Зарегистрировать новую папку с динамическими библиотеками:

  1. Добавить новый conf-файл в /etc/ld.so.conf.d.
  2. # ldconfig
    

Вывести все-все динамические библиотеки, нужные бинарнику:

$ ldd ⟨binary file⟩

Вывести все-все динамические библиотеки, нужные бинарнику, в виде дерева (нужен пакет pax-utils):

$ lddtree ⟨binary file⟩

Вывести только прямые зависимости бинарника:

$ readelf -d ⟨binary file⟩

Вывести строку исходного кода, которая соответствует адресу:

$ addr2line -f -e okularGenerator_poppler.so 0x37e82

Примечание: -f повелевает также вывести название функции.

DEB-пакеты

Вывести список установленных пакетов:

$ apt list --installed

Вывести список файлов установленного пакета:

$ dpkg -L ⟨package⟩

Вывести пакет, из которого появился файл:

$ dpkg -S ⟨path⟩

Вывести полное дерево зависимостей пакета (нужен пакет apt-rdepends):

$ apt-rdepends ⟨package⟩

Вывести список пакетов, которые зависят от искомого:

$ apt-cache rdepends ⟨package⟩

Вывести версию конкретного пакета:

$ aptitude search '^corosync$' -F '%V'

Вывести доступные версии пакета:

$ apt list -a ⟨package⟩

Выпилить установленные автоматически пакеты, которые больше не нужны:

# sudo apt-get autoremove

Пометить пакет как установленный вручную, дабы его ненароком не удалило:

# apt-mark manual ⟨package⟩

Поставить пакет на hold (запретить обновление) и снять:

# apt-mark hold ⟨package⟩
# apt-mark unhold ⟨package⟩

Вывести список пакетов, поставлекнных на hold:

# apt-mark showhold

Удалить скачанные deb-пакеты (лежат в /var/cache/apt/archives):

# apt-get clean

Обновиться на новый релиз:

# aptitude update
# aptitude full-upgrade

Установить пакет из файла:

# dpkg -i in.deb

Примечания:

  1. Осторожно! Оно не проверяет зависимости до начала установки.
  2. --force-all для игнора проблем с зависимостями.
  3. --force-architecture отключает проверку архитектуры.
  4. Чтобы установить не в /: --force-not-root --root=⟨path⟩. Пригодится при кросс-компиляции.

Распаковать deb-файл:

$ dpkg -x in.deb ⟨target directory⟩

Расшифровки интерфейса aptitude: p = пакет не установлен, i = установлен, v = виртуальный, A = установлен автоматически.

Скачать deb-файл (3 варианта):

$ apt download ⟨package⟩
$ apt-get download ⟨package⟩
$ aptitude download ⟨package⟩

Репозитории

Для подключения репозитория в /etc/apt/sources.list добавляется строка:

deb ⟨repo location⟩ ⟨distribution⟩ ⟨component1⟩ ⟨component2⟩ ⟨component3⟩...

Примечания:

  1. Доступные дистрибутивы можно посмотреть в каталоге ⟨repo location⟩/dists.
  2. Тут же можно указать ключ, например:
    deb [signed-by=/usr/share/keyrings/deriv-archive-keyring.gpg] https://deriv.example.net/debian/ stable main
    

Добавить публичный ключ репозитория (нужен пакет gnupg):

$ wget -O- ⟨URL⟩ | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/⟨name⟩.gpg

Для использования прокси добавляем в /etc/apt/apt.conf:

Acquire::http:Proxy "http://⟨host⟩:⟨port⟩";

Построить корневую ФС на примере Debian Bullseye:

# debootstrap --arch amd64 bullseye ⟨path⟩ http://ftp.se.debian.org/debian

Примечания:

  1. mmdebstrap — это альтернатива debootstrap, которая может работать без прав суперпользователя.

Сборка DEB-пакетов

Содержимое каталога debian:

  1. control — содержит список пакетов и их настройки.
  2. changelog — это история изменений.
  3. rules — это исполняемый Makefile, управляющий сборкой. Минимальный rules:
    #!/usr/bin/make -f
    
    %:
        dh $@
    
  4. ⟨package⟩.conffiles — тут можно перечислить конфигурационные файлы по 1 на строку, чтобы их не перезаписало без спроса при обновлении пакета. Обычно в этом нет нужды, т.к. всё в /etc по умолчанию считается конфигурационными файлами.
  5. ⟨package⟩.preinst и ⟨package⟩.postinst — скрипты, выполняемые до и после установки пакета.
  6. ⟨package⟩.prerm и ⟨package⟩.postrm — скрипты, выполняемые до и после удаления пакета.

Опция Replaces позволяет нашему пакету заменить файлы из другого пакета. После установки эти заменённые файлы будут числиться за нашим пакетом (это видно по dpkg -L). Обновление оригинального пакета не заменит наши файлы. Удаление нашего пакета удалит эти файлы, т.е. оригинальный пакет будет де-факто сломанным (aptitude reinstall в помощь).

Примеры применения профилей (build profiles):

  1. Включение/отключение сборки конкретного пакета:
    Build-Profiles: <astra>
    
  2. Подключение/отключение зависимостей:
    Build-Depends: libkf5kjs-dev <!astra>, ...
    Recommends: okular-csp-chm <!astra>, ...
    

Собрать пакеты из папки с исходниками (нужны пакеты devscripts, build-essential, lintian):

$ debuild --no-tgz-check -us -uc

Примачения:

  1. Флаг -d повелевает игнорировать зависимости.
  2. --build-profiles ака -P позволяет невозбранно задавать профили через запятую.

Скачать из репозитория исходники и собрать пакет:

  1. Скачать исходники пакета:
    $ apt-get source ⟨package⟩
    
  2. Пропатчить что-то, если нужно.
  3. $ apt-get -b source ⟨package⟩
    

Выпустить новую версию пакета с gbp (без пересборки):

$ gbp dch --upstream-branch=main --debian-branch=debian --release --commit
$ gbp buildpackage --git-tag-only --git-upstream-branch=main --git-debian-branch=debian

Вывести последнюю версию в файле debian/changelog:

$ dpkg-parsechangelog --show-field Version

Патчинг c quilt

Применить/отменить все патчи:

$ quilt push -a
$ quilt pop -a

Примечание: можно указать каталог с патчами при помощи QUILT_PATCHES.

Создать патч:

  1. $ quilt new ⟨patch name⟩
    
  2. $ quilt add ⟨file⟩
    
    Можно вызвать несколько раз для разных файлов.
  3. Правим файлы (НЕ в папке .pc).
  4. $ quilt refresh
    

RPM-пакеты

Вывести список установленных пакетов (2 варианта):

$ rpm -qa
$ yum list installed

Вывести зависимости пакета:

$ rpm -qR ⟨package⟩

Вывести changelog:

$ rpm -q --changelog ⟨package⟩

Вывести список файлов, установленных пакетом (2 варианта):

$ rpm -ql ⟨package⟩
$ repoquery --list ⟨package⟩

Вывести пакет, из которого появился файл:

$ rpm -qf ⟨path⟩

Импортировать ключ репозитория:

$ rpm --import ⟨key file⟩

Вывести переменные basearch и releasever, используемые в repo-файлах:

$ dnf config-manager --dump-variables

Распаковать RPM-архив в текущий каталог:

$ rpm2cpio in.rpm | cpio -idmv

Скопировать реп (нужен пакет dnf-utils):

$ reposync --newest-only --delete --norepopath --repoid=⟨repo id⟩ -p ⟨path⟩

Построить корневую ФС на примере Fedora 36:

$ curl -O https://raw.githubusercontent.com/hercules-team/augeas/master/tests/root/etc/yum.repos.d/fedora.repo
# dnf install -y --nogpgcheck --config=fedora.repo --releasever=36 --installroot=⟨path⟩ fedora-release systemd util-linux rootfiles

Сборка RPM-пакетов

Скачать исходники пакета (файл src.rpm):

$ yumdownloader --source ⟨package⟩

Собрать RPM-пакеты из src.rpm:

$ rpmbuild --rebuild in.src.rpm

Собрать RPM-пакеты по SPEC-файлу:

  1. Скачать исходники (нужен пакет rpmdevtools):
    $ spectool -g -R in.spec
    
  2. Собрать RPM-пакеты (нужен пакет rpm-build):
    $ rpmbuild -bb in.spec
    
    Примечание: если нужен пакет src.rpm, то использовать -ba.

Вывести SPEC-файл с раскрытими макросами:

$ rpmspec --parse in.spec

Вывести бинарные пакеты, определённые в SPEC-файле:

$ rpmspec --query in.spec

Вывести бинарные пакеты, определённые в SPEC-файле, в заданном формате:

$ rpmspec --query --qf '%{name}: %{version} %{release}\n' in.spec

Вывести версию пакетов, определяемых в SPEC-файле:

$ rpmspec --srpm --query --qf '%{version}' in.spec

Примечения:

  1. Флаг --rpms повелевает работать с бинарными пакетами, определёнными в spec-файле (по умолчанию). Флаг --srpm — с source-пакетом.

Вывести макрос:

$ rpm --eval '%{_datadir}'

Ядро, модули ядра

Вывести параметры, с которыми сейчас загружена ОС:

$ /proc/cmdline

Вывести все загруженные модули ядра (нужен пакет kmod):

$ lsmod

Загрузить модуль ядра из произвольного места:

# insmod ⟨path⟩ ⟨options⟩

Не умеет подгружать нужные зависимости, лишь ругается, если они не удовлетворены.

Выгрузить модуль:

# rmmod ⟨module⟩

modprobe работает поверх низкоуровневых insmod и rmmod. Загрузить модуль c зависимостями:

# modprobe ⟨module⟩ ⟨options⟩

Избавиться от дурацких пиков системного динамика:

# echo "blacklist pcspkr" | tee /etc/modprobe.d/nobeep.conf

Сборка ядра

  1. Создать .config:
    $ cp -v /boot/config-$(uname -r) .config
    
  2. Настроить .config:
    $ make menuconfig
    
  3. $ make
    
  4. Установить модули ядра:
    # make modules_install
    
  5. Установить ядро:
    # make install
    
  6. Обновить Grub на Debian/Ubuntu:
    # update-initramfs -c -k ⟨version⟩
    # update-grub
    

Разработка

При помощи --always-make можно заставить make выполнить сборку, даже если он считает, что она не требуется.

pkg-config

pkg-config предоставляет средства для подключения к проекту библиотек с учётом их зависимостей. Каждый модуль pkg-config представляет собой текстовый файл. Пример:

$ cat /usr/lib/x86_64-linux-gnu/pkgconfig/poppler-glib.pc
prefix=/usr
libdir=/usr/lib/x86_64-linux-gnu
includedir=/usr/include

Name: poppler-glib
Description: GLib wrapper for poppler
Version: 20.09.0
Requires: glib-2.0 >= 2.41 gobject-2.0 >= 2.41 cairo >= 1.10.0
Requires.private: poppler = 20.09.0

Libs: -L${libdir} -lpoppler-glib
Cflags: -I${includedir}/poppler/glib

Модули pkg-config живут в каталоге с библиотеками, например, /usr/lib/x86_64-linux-gnu/pkgconfig. При помощи переменной окружения PKG_CONFIG_PATH можно указать дополнительные каталоги с модулями.

Вывести все известные модули:

$ pkg-config --list-all

Вывести C-флаги модуля:

$ pkg-config --cflags glib-2.0

Вывести флаги библиотек модуля:

$ pkg-config --libs glib-2.0

Autotools

Примерная последовательность действий (нужны пакеты autoconf, automake, libtool):

$ aclocal
$ autoheader
$ automake --add-missing
$ autoreconf -ivf
$ mkdir build && cd build
$ ../configure
$ make

Флаги кладутся в CFLAGS, CXXFLAGS, LDFLAGS.

Для кросс-компиляции:

  1. Если компилятор нестандартный, то добавить в PATH путь к папке bin, в которой лежит компилятор.
  2. При вызове configure указать параметры --build=x86_64-linux-gnu, --host=mipsel-linux-gnu.
  3. Если нужно окружение, то задать --sysroot=<path> в CFLAGS и переменные окружения PKG_CONFIG_LIBDIR и PKG_CONFIG_SYSROOT_DIR.

CMake

См. заметки по CMake.

gdb

Некоторые варианты задания точек останова:

  1. break ⟨file name⟩:⟨line number⟩
    
  2. break ⟨file name⟩:⟨function⟩
    
  3. break ⟨function⟩
    

Вывести список потоков:

info threads

Переключиться на поток №1:

thread 1

Отладка внешних процессов:

  1. Подключиться к существующему процессу (при этом он останавливается):
    attach ⟨pid⟩
    
  2. Продолжить выполнение процесса:
    cont
    
  3. Освободить процесс (при этом он продолжит выполнение):
    detach
    

Значения параметра follow-fork-mode:

  1. parent (по умолчанию) — при вызове fork() или vfork() GDB продолжит дебажить родительский процесс.
  2. child — при вызове fork() или vfork() GDB переключится на дочерний процесс.

Значения параметра detach-on-fork:

  1. on (по умолчанию) — GDB может дебажить только 1 процесс (либо родительский либо дочерний в зависимости от follow-fork-mode).
  2. off — при вызове fork() или vfork() GDB будет дебажить и родительский и дочерний процесс.

Вывести значение параметра:

show ⟨param⟩

Установить значение параметра:

set ⟨param⟩ ⟨value⟩

Python

Вывести список установленных пакетов:

$ pip list

Создать файл requirements.txt:

$ pip freeze --local > requirements.txt

Установить пакеты, указанные в requirements.txt:

$ pip install -r requirements.txt

Создать изолированное окружение myenv при помощи venv:

$ python -m venv myenv
$ source myenv/bin/activate
$ deactivate

Примечания:

  1. При работе в окружении используются python и pip из каталога myenv/bin.
  2. venv — это стандартный модуль, появившийся в 3.3, урезанная версия проекта virtualenv.

Вывести настроки Django:

$ python manage.py diffsettings --all

Скрипты на Bash

Шапка:

#!/bin/bash

set -e повелевает прервать выполнение скрипта, если какая-либо команда вернёт ошибку.

Завершить выполнение скрипта с заданным кодом:

exit ⟨code⟩

Передать все аргументы другому скрипту:

another_script.sh "$@"

Функции

Функции ведут себя аналогично командам. Объявление функции и её вызов:

function f() {
    echo "I am f()"
}
f

Функция получает аргументы, пишет в stdout и возвращает код:

function sum() {
    echo $(($1 + $2))
    return 33
}
output=$(sum 10 6)
rc=$?
echo "$rc $output"

Блок if

В общем случае:

if ⟨command⟩
then
    echo 'return code == 0'
else
    echo 'return code != 0'
fi

Для строк есть == и !=. Для чисел есть -eq, -ne, -lt (меньше), -gt (больше), -le и -ge. Пример:

var=11
if [ $var -eq 10 ]
then
    echo 'var == 10'
elif [ $var -eq 11 ]
then
    echo 'var == 11'
else
    echo 'var != 10, var != 11'
fi

Иные проверки:

  1. Регулярки:
    [[ 'fail' == f* ]]
    
  2. Проверить, что строка не пуста:
    [ -n "${HOME}" ]
    
  3. Проверить, что файл или каталог существует:
    [ -e /etc/resolv.conf ]
    
  4. Проверить, что обычный файл или ссылка на файл существует:
    [ -f /etc/resolv.conf ]
    
  5. Проверить, что обычный файл существутет и его размер больше 0:
    [ -s /etc/resolv.conf ]
    
  6. Проверить, что каталог или ссылка на каталог существует:
    [ -d /etc/X11 ]
    
  7. Для отрицания добавляется !:
    [ ! -f /etc/resolv.conf ]
    

Поскольку выражения в скобках отдают код возврата, то можно делать:

  1. Сложные условия:
    if [ -d /etc/X11 ] && [ -f /usr/bin/Xorg ]
    then
        ...
    fi
    
  2. Простые проверки без блока if:
    [ -f /etc/resolv.conf ] || exit 1
    

См. также:

  1. Introduction to if

Блок case

var=11
case "${var}" in
    10)
        echo "10"
        ;;
    11 | 12 | 13)
        echo "11 | 12 | 13"
        ;;
    *)
        echo "ХЗ"
        ;;
esac

Циклы

while со счётчиком:

count=0
while [ $count -lt 10 ]
do
    echo "$count"
    (( count++ ))
done

Обход файлов:

find . -maxdepth 1 -name "*" | while read f
do
    echo "$f"
done

for с массивом:

strings=(
    str0
    str1
    "str with spaces"
)
for i in "${strings[@]}"
do
    echo "$i"
done

for со строкой:

items="0 1 2 3 4 5"
for i in $items
do
    echo "$i"
done

for с диапазоном:

for i in {0..10}
do
    echo "$i"
done

Также доступны break и continue.

Прочее

Перейти в предыдущую папку:

$ cd -

Мониторить вывод какой-то команды:

$ watch ⟨command⟩

Вывести время в заданном формате:

$ date +'%d.%m.%Y %H:%M:%S'

Вывести Unix timestamp:

$ date +%s

Запустить VNC-сервер для доступа к текущему дисплею:

  1. Задать пароль в ~/.vnc/passwd:
    $ x11vnc -storepasswd
    
  2. Запустить VNC-сервер:
    $ x11vnc -noxdamage -shared -dontdisconnect -many -noxfixes -rfbauth ~/.vnc/passwd
    

Если команда выполнилась с ошибкой, то выполнить другую:

$ ⟨command 1⟩ || ⟨command 2⟩

Арифметическое выражение:

$ echo $((6+6))

Вывести код возврата последней команды:

$ echo $?

Вывести PID интерпретатора:

$ echo $$

Для мониторинга I/O есть iftop и iotop.

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

$ ⟨var⟩=`⟨command⟩`

Для корректной работы Bluetooth-устройств, связанных с аудио, нужен pulseaudio-module-bluetooth:

  1. # aptitude install pulseaudio-module-bluetooth
    
  2. Перезапустить pulseaudio:
    $ pulseaudio -k
    $ pulseaudio --start
    

xargs берёт данные из stdin или из файла, разбивает их в соответствии с указанными параметрами и скармливает другой программе в качестве аргумента. Удалить файлы по шаблону *.sh:

$ find . -name '*.sh' | xargs rm -f

Установить минимальный набор пакетов для работы с LaTeX:

# aptitude install texlive texlive-base texlive-lang-cyrillic texlive-latex-extra texlive-font-utils

youtube-dl

youtube-dl из пакетов ОС обычно бесполезен. Надо ставить pipкой самый свежий:

$ pip3 install youtube-dl

Скачать видео в 720p:

$ youtube-dl -f 'bestvideo[height=720][ext=mp4]+bestaudio[ext=m4a]' ⟨url⟩

Примечания:

  1. --write-auto-sub для загрузки автоматически сгенерированных субтитров.
  2. --write-sub для загрузки пользовательских субтитров.

Скачать аудио дорожку:

$ youtube-dl -x --audio-format mp3 ⟨url⟩

yt-dlp — это форк с поддержкой многопоточности, аргументы те же.

Манипуляции с документами

Сгенерировать многостраничный TIF из нескольких JPG (нужен пакет imagemagick):

$ convert -compress jpeg -quality 50 ⟨directory⟩/*.jpg ⟨output TIF⟩

Распилить многостраничный TIF на отдельные картинки:

$ convert in.tif %d.tif

Перегнать svg в png/pdf/eps (нужен пакет librsvg2-bin):

$ rsvg-convert --format=png --output=out.png in.svg

Получить разницу между 2 изображениями в виде 3-го изображения (нужен пакет imagemagick):

$ compare -compose src in1.png in2.png out.png

Вывести количество отличающихся пикселей:

$ compare -metric AE in1.png in2.png out.png

Вывести инфу по изображению (нужен пакет imagemagick):

$ identify -verbose ⟨path⟩

Проверить целостность PNG-файла + вывести инфу по нему (нужен пакет pngcheck):

$ pngcheck ⟨PNG file⟩

Сгенерировать PDF-файл без сжатия:

$ qpdf --qdf --object-streams=disable --stream-data=uncompress --generate-appearances in.pdf out.pdf

Снять пароль с PDF-файла:

$ qpdf --decrypt --password=⟨password⟩ in.pdf out.pdf

Получить 1-ю страницу PDF-файла в виде изображения (нужен пакет poppler-utils):

$ pdftoppm -singlefile -f 1 -r 72 -png in.pdf out

About

Заметки по Linux для самых маленьких

Topics

Resources

License

Stars

Watchers

Forks