Оригинал — github.com/ololobster/linux-cli.
- Введение: shell и виртуальные консоли, SSH, SSH-прокси, конвейер и потоки, подстановка путей файлов по шаблону
- Информация о системе: пользовательские лимиты
- ФС: LVM, монтирование
- Манипуляции с файлами: rsync и scp, архивы, права, find
- Манипуляции с текстом: grep, sed, vim
- Сеть: interfaces, NetworkManager, systemd-networkd, curl
- Пользователи: sudo и su, локаль
- Службы systemd: создание службы, монтирование с systemd
- Переменные окружения
- Криптография и безопасность: контрольные суммы, gpg, КриптоПро, Astra Linux, пакет ldap-utils
- Исполняемые файлы и библиотеки
- DEB-пакеты: репозитории
- Сборка DEB-пакетов: патчинг c quilt
- RPM-пакеты
- Сборка RPM-пакетов
- Ядро, модули ядра
- Разработка: pkg-config, Autotools, CMake, gdb, Python
- Скрипты на Bash: функции, блок if, блок case, циклы
- Прочее: youtube-dl, манипуляции с документами
Shell — это интерпретатор командной строки. Вывести текущий интерпретатор:
$ echo $SHELL
Классификация login/non-login:
- Login shell — это shell, который запускается при входе пользователя в систему.
- Non-login shell — это shell, который запускается уже находящимся в системе пользователем.
Это можно посмотреть так (если есть чёрточка, то это login shell):
$ echo $0
-bash
Классификация interactive/non-interactive:
- Interactive shell — это shell, в котором можно печатать и прерывать выполнение команд.
- 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:
$ ssh ⟨user⟩@⟨server⟩
Примечания:
- Можно использовать конкретный ключ для аутентификации:
-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⟩
Примечания:
- Это добавит новый публичный ключ в файл
~/.ssh/authorized_keys
на сервере. - Если всё равно просит пароль, то на сервере проверяем права
authorized_keys
(должно быть600
) и родительского каталога (должно быть700
).
Удалить хост из файла known_hosts
:
$ ssh-keygen -f ~/.ssh/known_hosts -R ⟨host⟩
Некоторые настройки SSH-сервера (/etc/ssh/sshd_config
):
PasswordAuthentication
(yes
илиno
) — разрешена ли аутентификация по паролю.PermitRootLogin
(yes
,prohibit-password
,forced-commands-only
илиno
) — можно ли root'у зайти по SSH.prohibit-password
означает, что таки можно, но только по ключу.AddressFamily
,Port
иListenAddress
— настройки соединения.
Дано:
- у нас проброшены ключи к
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⟩
Примечания:
- Все команды в конвейере выполняются параллельно, каждая в своем процессе.
- Попытка чтения из пустого буфера блокирует процесс, равно как и попытка записи в заполненный буфер.
- Вывод ошибок (stderr) не перенаправляется.
- Код завершения конвейера — это код завершения последней команды.
Это можно изменить с
$ 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
):
- Один раз:
# updatedb
-
$ locate ⟨file⟩
Вывести load average для 1, 5 и 15 минут (2 варианта):
$ cat /proc/loadavg
$ uptime
Вывести инфу по пространствам имён Linux:
# lsns
Вывести все лимиты текущего пользователя:
$ ulimit -a
Чтобы вывести конкретный лимит используем нужный флаг.
Некоторые параметры:
nofile
(флаг-n
) — максимальное количество открытых файлов.nproc
(флаг-u
) — максимальное количество процессов.stack
(флаг-s
) — максимальный размер стека в Кб.fsize
(флаг-f
) — максимальный размер файла в Кб.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⟩
Примечания:
- Примеры типов:
ext4
,vfat
. - Раздел не должен быть смонтирован.
Записать загрузочный USB (указывать диск, например, /dev/sdb
):
# dd bs=4M if=in.iso of=⟨device⟩ conv=fdatasync
Начать работу с parted
в интерактивном режиме (указывать диск, например, /dev/sdc
):
# parted ⟨disk device⟩
Примечания:
mklabel GPT
— выпилить все данные на диске, создать таблицу разделов в формате GPT.mkpart ⟨label⟩ ext4 2048s 100%
— создать раздел с ext4 на весь диск.p
акаprint
— вывести инфу по выбранному диску.q
акаquit
— выйти.fdisk
пока умеет только в таблицу разделов DOS.- Не забываем отформатировать новые разделы.
Чтобы увеличить размер ФС, надо удалить раздел и пересоздать его с новым размером:
# fdisk /dev/vda
p
d
n
p
# resize2fs /dev/vda1
При пересоздании раздела надо указывать тот же начальный сектор, что был изначально.
Выполнить команду, отключив fsync()
:
$ eatmydata ⟨command⟩
Найти процессы, использующие файл или папку:
$ lsof | grep ⟨file or directory⟩
Примечания:
-p
позволяет задать нужный PID или сразу несколько через запятую. Можно исключать ненужные при помощи^
, например,^1,^2,^3
.-u
позволяет задать нужного пользователя или сразу несколько через запятую. Можно исключать ненужных при помощи^
, например,^root,^georgiy
.
Вывести список процессов, которые используют файлы:
$ lslocks
Примечания:
-p
ака--pid
позволяет задать нужный процесс.- Если процесс заблокирован из-за того, что файл уже используется, то в колонке
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⟩
Warning: если сдохнет один из HDD, управляемых LVM, то можно потерять все данные.
Вывести инфу по группам томов:
# vgdisplay
Вывести инфу по томам:
# lvdisplay
Создать группу томов:
# vgcreate -c n ⟨group name⟩ ⟨partion device 1⟩ ... ⟨partion device N⟩
Примечания:
- Есть флаг
--yes
.
Создать том, занимающий 100% объёма своей группы:
# lvcreate -l 100%VG -n ⟨volume name⟩ ⟨group name⟩
Примечания:
-l
ака--extents
также позволяет указать % от свободного места, например,-l 100%FREE
.-L
ака--size
позволяет указать точный размер, например,-L 10g
.- Теперь надо отформатировать
/dev/⟨group name⟩/⟨volume name⟩
и можно монтировать.
Расширить том:
- Убедиться, что в группе есть свободное место.
- Расширить том:
Количество доступных PE (physical extents) можно посмотреть в свойствах группы.
# lvextend -l +⟨PE⟩ ⟨volume path⟩
- Расширить ФС.
Например, для 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⟩ ...
Примечания:
-n
ака--iterations
позволяет задать количество проходов.-z
ака--zero
указывает выполнить финальный проход с заполнением нулями.-u
указывает удалить файл в конце.
Копировать с rsync
:
$ rsync ⟨source⟩ ⟨target directory⟩
Примечания:
- Можно качать по SSH —
⟨user⟩@⟨host⟩:⟨path⟩
. При этомrsync
должен быть установлен и на удалённой машине. - Если надо копировать содержимое каталога, то добавляем
/
в конце пути. Если надо копировать сам каталог, то не добавляем. -r
ака--recursive
— рекурсивно копировать папку.-l
ака--links
— копировать символьные ссылки как символьные ссылки.-e
ака--rsh
позволяет задать shell. Например, задаём нестандартный порт:--rsh='ssh -p 222'
.--exclude
позволяет игнорировать ненужные файлы, причём аргументов--exclude
может быть несколько. Пример:--exclude=*.pdf
.
Копировать с scp
:
$ scp ⟨source⟩ ⟨target directory⟩
Примечания:
- Можно качать по SSH —
⟨user⟩@⟨host⟩:⟨path⟩
. -r
— рекурсивно копировать папку.- Если надо указать порт, то используем
-P
. 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 .
Примечания:
- Можно указать сразу много файлов и каталогов.
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⟩
Примечания:
-R
повелевает применить изменения рекурсивно.- Комбинация
-d -m
указывает, что создаётся правило по умолчанию (Default ACL) для каталога. Это правило будет применяться к создаваемым там файлам. - Для полного запрета указываем права
0
.
Поиск больших логов:
$ 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⟩
Вывести строки, включающие паттерн ⟨pattern⟩
:
$ ⟨command⟩ | grep ⟨pattern⟩
Вывести строки, удовлетворяющие регулярке ⟨pattern⟩
:
$ ⟨command⟩ | grep -e '⟨pattern⟩'
Вывести строки, которые не включают паттерн ⟨pattern⟩
:
$ ⟨command⟩ | grep -v ⟨pattern⟩
Примечания:
- Флаг
--ignore-case
ака-i
повелевает игнорировать регистр. По умолчанию учитывается. --max-count
ака-m
позволяет ограничить количество результаов.- Оператор ИЛИ в шаблоне:
samba\|smbd
. - Выводить также N строк перед найденной строкой:
-B ⟨N⟩
. - Выводить также N строк после найденной строки:
-A ⟨N⟩
.
Проверить наличие строки в файле:
$ grep --quiet ⟨pattern⟩ ⟨path⟩
Примечание: если есть — вернёт 0
, нет — вернёт 1
.
Если не указать файл, то sed
будет читать из stdin.
-i
ака --in-place
повелевает перезаписать файл (по умолчанию пишет в stdout).
Заменить в файле одну строку на другую:
$ sed -i 's/⟨before⟩/⟨after⟩/g' ⟨file⟩
Например, избавиться от \r
: s/\r//g
.
Без флажка g
будет заменять лишь 1 раз в каждой строке (1-е вхождение).
Вместо g
можно указать номер вхождения, например, s/⟨before⟩/⟨after⟩/2
заменит 2-е вхождение ⟨before⟩
в каждой строке.
Если /
неудобен в качестве разделителя, то можно использовать другой символ, например, s!/usr/lib!/usr/share!g
.
Можно указать строки, с которыми надо работать, например:
1
— 1-я строка (нумерация строк идёт с 1);1,3
— строки с 1-й по 3-ю включительно;3,$
— все строки начиная с 3-й.
Например, добавить префикс к первым 3 строкам файла:
$ sed -i '1,3s/^/⟨prefix⟩/' ⟨file⟩
Прочие действия:
/⟨pattern⟩/s/⟨before⟩/⟨after⟩/g
— осуществить замену в строках, содержащих⟨pattern⟩
.3d
— удалить 3-ю строку./⟨pattern⟩/d
— удалить строки, содержащие⟨pattern⟩
.3c\⟨new line⟩
— заменить 3-ю строку.1i\⟨new line⟩
— добавить строку перед 1-й строкой (т.е. в самое начало).1a\⟨new line⟩
— добавить строку после 1-й строки.
При помощи ;
можно применить несколько действий за раз:
$ echo 'abcd' | sed 's/ab/xy/; s/cd/ab/; s/xy/cd/'
cdab
Команды vim
:
:w
— сохранить.:q
— выйти изvim
.:wq
— выйти изvim
с сохранением.:q!
— выйти изvim
без сохранения.:set number
ака:set nu
— отображать номера строк.:set nonumber
ака:set nu!
— не отображать номера строк.i
— войти в режим вставки.- Escape — выйти из режима вставки.
dd
— удалить строку./⟨search term⟩
— искать.n
— следующий,N
— предыдущий.u
ака:u
ака:undo
— отмена.
Вырезать и вставлять текст:
V
, чтобы выбрать нужные стороки (илиv
чтобы выбрать кусочек стороки).d
, чтобы вырезать.p
, чтобы вставить после курсора.
Вывести информацию об интерфейсе (нужен пакет ethtool
):
# ethtool ⟨interface⟩
Примечания: можно смотреть воткнут ли кабель в разъём.
Отключить интерфейс:
# ifconfig ⟨interface⟩ down
Вывести драйвер, используемый интерфейсом:
$ 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 и сообщает об ошибке.
Процесс повторяется до тех пор, пока пакет не достигнет целевого узла.
Пример интерфейса с 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
, то система не выдаст ошибку, а попробует подобрать маску самостоятельно.
Но делать так НЕ надо, надо задавать.
Вывести список устройств/соединений:
$ 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
Правило представляет собой файл с расширением .network
или .link
, лежащий в /etc/systemd/network
.
Пример: 10-persistent-net.link
.
Задать название интерфейса (требуется расширение .link
):
[Match]
MACAddress=⟨mac⟩
[Link]
Name=⟨name⟩
Примечания:
- Если уж назначать имена, то всем, иначе возможны глюки с появлением интерфейсов типа
rename5
. - 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 --output ⟨path⟩ ⟨url⟩
Примечания:
--output
ака-o
— это именно новый файл, НЕ каталог. В качестве альтернативы есть--remote-name
ака-O
(оставить оригинальное имя файла) и--output-dir
(по умолчанию текущий каталог).
Вывести HTTP-заголовки:
$ curl --head ⟨url⟩
Отправить простой POST-запрос (application/x-www-form-urlencoded
):
$ curl -d '[email protected]&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⟩
Примечания:
- Для бинарных данных следует использовать не
--data
ака-d
, а--data-binary
.
Используемые 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
Стать другим пользователем:
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
.
Где лежат конфиги сервисов:
/usr/lib/systemd/user
;/run/systemd/system
;/etc/systemd/system
.
Перезагрузить конфиги сервисов:
# systemctl daemon-reload
Получить статистику запуска сервисов:
$ systemd-analyze plot > out.svg
Типы служб:
- simple — главный процесс и является службой.
- forking — процесс порождает дочерний процесс и выходит. Systemd считает службу запущенной, хоть процесс и завершился.
- oneshot — процесс будет короткоживущим. Systemd ждёт его завершения прежде чем запускать зависимые от него службы.
- notify — служба выпустит оповещение, когда она будет готова. Systemd ждёт оповещения прежде чем запускать зависимые от неё службы.
- idle — Systemd отложит запуск процесса до момента выполнения всех остальных задач, в остальном аналог simple.
- dbus — служба считается запущенной, когда её имя появится в системной шине DBus.
Минимальный пример service-файла:
[Unit]
Description=⟨description⟩
[Service]
Type=simple
ExecStart=⟨command⟩
[Install]
WantedBy=multi-user.target
Примечания по секции Unit
:
Before
иAfter
— нужно запускать до/после какого-либо сервиса.Requires
— зависимость. Если при старте происходит взаимодействие с другим сервисом, то его надо прописать и вRequires
и вAfter
. Если задан лишьRequires
, то оба будут запущены одновременно.BindsTo
— то же что иRequires
+ наш сервис будет остановлен при остановке зависимости.Wants
— слабая версияRequires
. Наш сервис будет выполняться, даже если systemd не сумеет запустить эту зависимость.Conflicts
— какой-либо сервис, одновременная работа с которым невозможна.- Любой из параметров
Before
,After
,Requires
,BindsTo
,Wants
,Conflicts
может встречаться по несколько раз. - Можно задать условия запуска:
AssertPathExists
,AssertPathIsReadWrite
,AssertDirectoryNotEmpty
,AssertFirstBoot
и т.д.
Примечания по секции Service
:
ExecStart
,ExecReload
,ExecRestart
,ExecStop
— команды для запуска, релоада, перезапуска и остановки службы.ExecStartPre
иExecStartPost
— доп. команды, выполняемые до и послеExecStart
, например, чтобы создать папку под pid-файл в/var/run
. При этомExecStartPost
является частью процедуры запуска; пока он не отработает зависимые службы не запускаются.ExecStopPost
— доп. команда, выполняемая после остановки службы.- В
ExecStart
и ко надо использовать абсолютные пути, например,/bin/mountpoint
. WorkingDirectory
— рабочая папка.EnvironmentFile
— путь к файлу с переменными окружения (обычно в/etc/default
).TimeoutStartSec
— таймаут на старт службы,TimeoutStopSec
— таймаут на остановку службы,TimeoutSec
— единое значение для обоих таймаутов.
Примечания по секции Install
:
- Если секции нет, то нельзя выполнить
systemctl enable
. Т.е. если служба не самостоятельна, а является лишь зависимость для других служб, то секция не нужна. - Доступные цели: poweroff.target (runlevel0) — выключение, rescue.target (runlevel1) — rescue shell готов, multi-user.target (runlevel2, 3, 4) — пользователи могут логиниться и использовать CLI, graphical.target (runlevel5) — пользователи могут использовать графический режим, reboot.target (runlevel6) — перезагрузка.
Пример 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
Примечания:
- Имя mount-файла должно соответствовать точке монтирования.
Например,
/var/lockvol
—var-lockvol.mount
. - Команда
systemctl start
монтирует,systemctl stop
— отмонтирует. ExecStartPre
и ко недоступны.- При работе с Gluster может понадобиться обеспечить задержку для корректного монтирования.
Вывести все переменные окружения:
$ printenv
Выполнить одну команду с нужными переменными окружения:
$ ⟨var1⟩=⟨value1⟩ ⟨var2⟩=⟨value2⟩ ⟨command⟩
Заданные переменные станут переменными окружения в порождённом процессе.
А в текущем процессе не станут, поэтому использовать их в качестве аргумента команды не выйдет.
Например, так не сработает, echo
выведет пустую строку:
$ i=1 echo "$i"
Так сработает:
$ i=1 bash -c 'echo "$i"'
Локальные переменные (для текущей сессии) задаются и удаляются так:
$ export ⟨var⟩=⟨value⟩
$ unset ⟨var⟩
Переменные для конкретного пользователя лежат в
~/.bashrc
— выполняется при старте нового процесса Bash пользователем, который уже находится в системе (non-login shell).~/.bash_profile
(или~/.profile
) — выполняется при старте нового процесса Bash, когда пользователь входит по SSH (login shell).
Переменные для всех пользователей лежат в
/etc/bash.bashrc
— то же, что и~/.bashrc
, но для всех пользователей (только Debian и Ubuntu)./etc/profile
— то же, что и~/.bash_profile
, но для пользователей./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 --list-keys
Создать ключ:
$ gpg --full-generate-key
Экспортировать публичный ключ в виде key-файла:
$ gpg --armor --output ⟨output key file⟩ --export ⟨id⟩
Создать ЭП для файла in.txt
:
$ gpg --output out.sig --sign in.txt
Примечания:
- ЭП создаётся при помощи приватного ключа подписанта, а проверяется она при помощи соответствующего публичного ключа.
- 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
Примечания:
- Чтобы зашифровать сообщение Алисе, используется её публичный ключ, а расшировывать она будет своим приватным ключом.
- Для расшифровки использовать
--decrypt
(см. выше).
Вывести сертификаты в 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
Экспортировать сертификат без ключей (в виде CER-файла):
$ /opt/cprocsp/bin/amd64/certmgr -export -certificate -thumbprint ⟨sha1⟩ -dest out.cer
Создать отсоединённую ЭП для файла 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
Проверить работоспособность OCSP-службы:
$ /opt/cprocsp/bin/amd64/ocsputil makeresp -u ⟨OCSP server⟩ in.cer
Мандатная метка = метка безопасности = уровень конфиденциальности + набор категорий + уровень целостности. Классификационная метка = метка конфиденциальности = уровень конфиденциальности + набор категорий. Набор категорий хранится как число (битовая маска).
На БД и таблицы PostgreSQL, а также на IP-пакеты ляпаются классификационные метки (т.е. без уровня целостности).
Правила доступа:
- Субъект может изменять объект, если Lₛ = Lₒ, Cₛ = Cₒ, iLₛ ≥ iLₒ (уровни конфиденциальности и набор категорий совпадают, а уровень целостности субъекта не ниже чем у объекта).
- Субъект может читать объект, если Lₛ ≥ Lₒ, Cₒ ⊂ Cₛ. Уровни целостности не имеют значения.
Правила присвоения мандатных меток:
- Созданный субъект (например, дочерний процесс) наследует мандатную метку родительского субъекта.
- Созданный объект (например, файл) наследует классификационную метку родительского субъекта, а уровень целостности у него будет нулевой.
- Мандатная метка объекта-контейнера (например, каталога) определяет макс. мандатную метку его дочерних объектов.
Вывести мандатную метку текущей сессии:
$ pdp-id
Вывести мин. и макс. возможную мандатную метку пользователя:
# pdpl-user ⟨user⟩
Установить для пользователя допустимые уровни конфиденциальности:
# pdpl-user -l ⟨min level⟩:⟨max level⟩ ⟨user⟩
Установить для пользователя максимальный уровень целостности:
# pdpl-user -i ⟨max int level⟩ ⟨user⟩
Примечания:
- Эти ограничения для локального пользователя хранятся в
/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⟩
Примечания:
- Флаги перечисляются через запятую.
-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-запрос:
$ ldapsearch -H ldap://⟨host⟩ -LLL -Q -o ldif-wrap=no -b ⟨DN⟩ ⟨filter⟩
Примечания:
-Q
— использовать SASL-аутентификацию + тихий режим. Работает, если есть активный билет Kerberos.-LLL
— вывести результат в формате LDIF без комментариев и версии.-S
— атрибут, по которому происходит сортировка. Пустая строка означает сортировку по DN.-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⟩
Примечания:
- Может работать с LDIF-файлами как
ldapadd
.
Переменная окружения LD_LIBRARY_PATH
— это список каталогов, где ОС ищет динамические библиотеки, прежде чем обратиться к стандартным каталогам, заданным в /etc/ld.so.conf
.
Для Qt-приложений также есть QT_PLUGIN_PATH
.
Зарегистрировать новую папку с динамическими библиотеками:
- Добавить новый conf-файл в
/etc/ld.so.conf.d
. -
# ldconfig
Вывести все-все динамические библиотеки, нужные для запуска бинарника:
$ ldd ⟨binary file⟩
Вывести только прямые зависимости бинарника:
$ readelf -d ⟨binary file⟩
Вывести строку исходного кода, которая соответствует адресу:
$ addr2line -f -e okularGenerator_poppler.so 0x37e82
Примечание: -f
повелевает также вывести название функции.
Вывести список установленных пакетов:
$ 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
Примечания:
- Осторожно! Оно не проверяет зависимости до начала установки.
--force-all
для игнора проблем с зависимостями.--force-architecture
отключает проверку архитектуры.- Чтобы установить не в
/
:--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⟩...
Примечания:
- Доступные дистрибутивы можно посмотреть в каталоге
⟨repo location⟩/dists
. - Тут же можно указать ключ, например:
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
Примечания:
mmdebstrap
— это альтернативаdebootstrap
, которая может работать без прав суперпользователя.
Содержимое каталога debian
:
control
— содержит список пакетов и их настройки.changelog
— это история изменений.rules
— это исполняемый Makefile, управляющий сборкой. Минимальныйrules
:#!/usr/bin/make -f %: dh $@
⟨package⟩.conffiles
— тут можно перечислить конфигурационные файлы по 1 на строку, чтобы их не перезаписало без спроса при обновлении пакета. Обычно в этом нет нужды, т.к. всё в/etc
по умолчанию считается конфигурационными файлами.⟨package⟩.preinst
и⟨package⟩.postinst
— скрипты, выполняемые до и после установки пакета.⟨package⟩.prerm
и⟨package⟩.postrm
— скрипты, выполняемые до и после удаления пакета.
Опция Replaces
позволяет нашему пакету заменить файлы из другого пакета.
После установки эти заменённые файлы будут числиться за нашим пакетом (это видно по dpkg -L
).
Обновление оригинального пакета не заменит наши файлы.
Удаление нашего пакета удалит эти файлы, т.е. оригинальный пакет будет де-факто сломанным (aptitude reinstall
в помощь).
Примеры применения профилей (build profiles):
- Включение/отключение сборки конкретного пакета:
Build-Profiles: <astra>
- Подключение/отключение зависимостей:
Build-Depends: libkf5kjs-dev <!astra>, ... Recommends: okular-csp-chm <!astra>, ...
Собрать пакеты из папки с исходниками (нужны пакеты devscripts
, build-essential
, lintian
):
$ debuild --no-tgz-check -us -uc
Примачения:
- Флаг
-d
повелевает игнорировать зависимости. --build-profiles
ака-P
позволяет невозбранно задавать профили через запятую.
Скачать из репозитория исходники и собрать пакет:
- Скачать исходники пакета:
$ apt-get source ⟨package⟩
- Пропатчить что-то, если нужно.
-
$ 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
Применить/отменить все патчи:
$ quilt push -a
$ quilt pop -a
Примечание: можно указать каталог с патчами при помощи QUILT_PATCHES
.
Создать патч:
-
$ quilt new ⟨patch name⟩
-
Можно вызвать несколько раз для разных файлов.
$ quilt add ⟨file⟩
- Правим файлы (НЕ в папке
.pc
). -
$ quilt refresh
Вывести список установленных пакетов (2 варианта):
$ rpm -qa
$ yum list installed
Вывести зависимости пакета:
$ rpm -qR ⟨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
Скачать исходники пакета (файл src.rpm
):
$ yumdownloader --source ⟨package⟩
Собрать RPM-пакеты из src.rpm
:
$ rpmbuild --rebuild in.src.rpm
Собрать RPM-пакеты по SPEC-файлу:
- Скачать исходники (нужен пакет
rpmdevtools
):$ spectool -g -R in.spec
- Собрать RPM-пакеты (нужен пакет
rpm-build
):Примечание: если нужен пакет$ rpmbuild -bb in.spec
src.rpm
, то использовать-ba
.
Вывести бинарные пакеты, определённые в spec-файле:
$ rpmspec --query in.spec
Вывести бинарные пакеты, определённые в spec-файле, в заданном формате:
$ rpmspec --query --qf '%{name}: %{version} %{release}\n' in.spec
Вывести версию пакетов:
$ rpmspec --srpm --query --qf '%{version}' in.spec
Примечения:
- Флаг
--rpms
повелевает работать с бинарными пакетами, определёнными в spec-файле (по умолчанию). Флаг--srpm
— с source-пакетом.
Вывести все загруженные модули ядра (нужен пакет kmod
):
$ lsmod
Загрузить модуль ядра из произвольного места:
# insmod ⟨path⟩ ⟨options⟩
Не умеет подгружать нужные зависимости, лишь ругается, если они не удовлетворены.
Выгрузить модуль:
# rmmod ⟨module⟩
modprobe
работает поверх низкоуровневых insmod
и rmmod
.
Загрузить модуль c зависимостями:
# modprobe ⟨module⟩ ⟨options⟩
Избавиться от дурацких пиков системного динамика:
# echo "blacklist pcspkr" | tee /etc/modprobe.d/nobeep.conf
- Создать
.config
:$ cp -v /boot/config-$(uname -r) .config
- Настроить
.config
:$ make menuconfig
-
$ make
- Установить модули ядра:
# make modules_install
- Установить ядро:
# make install
- Обновить Grub на Debian/Ubuntu:
# update-initramfs -c -k ⟨version⟩ # update-grub
При помощи --always-make
можно заставить make
выполнить сборку, даже если он считает, что она не требуется.
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
Примерная последовательность действий (нужны пакеты autoconf
, automake
, libtool
):
$ aclocal
$ autoheader
$ automake --add-missing
$ autoreconf -ivf
$ mkdir build && cd build
$ ../configure
$ make
Флаги кладутся в CFLAGS
, CXXFLAGS
, LDFLAGS
.
Для кросс-компиляции:
- Если компилятор нестандартный, то добавить в
PATH
путь к папкеbin
, в которой лежит компилятор. - При вызове
configure
указать параметры--build=x86_64-linux-gnu
,--host=mipsel-linux-gnu
. - Если нужно окружение, то задать
--sysroot=<path>
вCFLAGS
и переменные окруженияPKG_CONFIG_LIBDIR
иPKG_CONFIG_SYSROOT_DIR
.
См. заметки по CMake.
Некоторые варианты задания точек останова:
-
break ⟨file name⟩:⟨line number⟩
-
break ⟨file name⟩:⟨function⟩
-
break ⟨function⟩
Вывести список потоков:
info threads
Переключиться на поток №1:
thread 1
Отладка внешних процессов:
- Подключиться к существующему процессу (при этом он останавливается):
attach ⟨pid⟩
- Продолжить выполнение процесса:
cont
- Освободить процесс (при этом он продолжит выполнение):
detach
Значения параметра follow-fork-mode
:
parent
(по умолчанию) — при вызовеfork()
илиvfork()
GDB продолжит дебажить родительский процесс.child
— при вызовеfork()
илиvfork()
GDB переключится на дочерний процесс.
Значения параметра detach-on-fork
:
on
(по умолчанию) — GDB может дебажить только 1 процесс (либо родительский либо дочерний в зависимости отfollow-fork-mode
).off
— при вызовеfork()
илиvfork()
GDB будет дебажить и родительский и дочерний процесс.
Вывести значение параметра:
show ⟨param⟩
Установить значение параметра:
set ⟨param⟩ ⟨value⟩
Вывести список установленных пакетов:
$ 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
Примечания:
- При работе в окружении используются
python
иpip
из каталогаmyenv/bin
. venv
— это стандартный модуль, появившийся в 3.3, урезанная версия проектаvirtualenv
.
Вывести настроки Django:
$ python manage.py diffsettings --all
Шапка:
#!/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 ⟨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
Иные проверки:
- Регулярки:
[[ 'fail' == f* ]]
- Проверить, что строка не пуста:
[ -n "${HOME}" ]
- Проверить, что файл или каталог существует:
[ -e /etc/resolv.conf ]
- Проверить, что обычный файл существует:
[ -f /etc/resolv.conf ]
- Проверить, что обычный файл существутет и его размер больше 0:
[ -s /etc/resolv.conf ]
- Проверить, что каталог существует:
[ -d /etc/X11 ]
- Для отрицания добавляется
!
:[ ! -f /etc/resolv.conf ]
Поскольку выражения в скобках отдают код возврата, то можно делать:
- Сложные условия:
if [ -d /etc/X11 ] && [ -f /usr/bin/Xorg ] then ... fi
- Простые проверки без блока
if
:[ -f /etc/resolv.conf ] || exit 1
См. также:
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
Если команда выполнилась с ошибкой, то выполнить другую:
$ ⟨command 1⟩ || ⟨command 2⟩
Арифметическое выражение:
$ echo $((6+6))
Вывести код возврата последней команды:
$ echo $?
Вывести PID интерпретатора:
$ echo $$
Для мониторинга I/O есть iftop
и iotop
.
Выполнить команду и сохранить её вывод:
$ ⟨var⟩=`⟨command⟩`
Для корректной работы Bluetooth-устройств, связанных с аудио, нужен pulseaudio-module-bluetooth
:
-
# aptitude install pulseaudio-module-bluetooth
- Перезапустить 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
из пакетов ОС обычно бесполезен.
Надо ставить pipкой самый свежий:
$ pip3 install youtube-dl
Скачать видео в 720p:
$ youtube-dl -f 'bestvideo[height=720][ext=mp4]+bestaudio[ext=m4a]' ⟨url⟩
Примечания:
--write-auto-sub
для загрузки автоматически сгенерированных субтитров.--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