Skip to content

Instantly share code, notes, and snippets.

@s3rgeym
Last active April 6, 2024 11:59
Show Gist options
  • Star 94 You must be signed in to star a gist
  • Fork 38 You must be signed in to fork a gist
  • Save s3rgeym/bd33f94ab96c96bc6719035fcac2b807 to your computer and use it in GitHub Desktop.
Save s3rgeym/bd33f94ab96c96bc6719035fcac2b807 to your computer and use it in GitHub Desktop.
Установка Arch Linux с шифрованием всего диска либо раздела и Btrfs

image

Вся суть харча™ (на самом деле все далеко не так...)

Установка Arch Linux с шифрованием всего диска либо раздела и Btrfs

Как записать образ на флешку

Качаем Ventoy.

Screenshot 2022-06-01 110230

Выбираем Option --> Partition style --> GPT как на скрине.

Качаем ISO-образ Arch Linux [ и копируем/перемещаем ] в корень на созданном разделе флешки.

Screenshot 2022-06-01 110523

Так же нужно выделить немного места под Arch Linux, если не предполагается использование отдельного диска.

Запускаем Explorer/Проводник и кливаем правой по иконке This PC/Этот Компьютер, выбираем Manage (перед этим нужно выбрать Show more options):

Screenshot 2022-06-01 130403

В Disk Managment нужно сжать какой-нибудь раздел, выделив под Arch 80-100GB:

Screenshot 2022-06-01 130613

Выбор загрузочного устройства в BIOS/UEFI

Во время включения компьютера при появлении логотипа жмем раза клавиши F2 / F12 / Del (зависит от производителя).

Во вкладке Boot отключаем Secure Boot. Это виндовое изобретение, которое не позволяет запускать неподписанные EFI. Можно еще включить Launch CSM / CMS Boot / CMS OS / Legacy OS для возможности загрузки с устройств, содержащих метку MBR (может потребоваться, например, для установки Windows 7). В этой же вкладке меняем приоритет загрузки устройств, делая флешку первой. Сохраняем изменения и выходим.

Когда загрузится Ventoy, выбираем в меню Arch Linux...

Выбор пароля

В качестве пароля указывайте фразу длинее 20 символов. Не используйте пароли, которые вами уже использовались на ресурсах, напрямую подключенных к СОРМ (Вконтакте, Одноклассники, Mail, Yandex, Rambler и тп), избегайте распространенных паролей, которые утекли в сеть, и, конечно, же не вздумайте проверять стойкость пароля через сайт Касперского (вы его просто добавите в базу для брута, которую используют правоохранительные органы). В качестве пароля можно использовать фразу на одном из вымирающих языков, например, абхазском или ады-гей-ском, набранную на английской раскладке. Взломостойкими являются бредовые фразы, так как такой пароль нельзя подобрать с помощью цепей Маркова (например, "краб катит листья яблок"). Так же можно намеренно допускать ошибки в словах. Помните Олбанский и «Онотоле, пыш-пыш»?

Касаемо, фраз, то их не советуют использовать, потому как с помощью цепей маркова в теории можно подобрать пароль. В документации советуют генерировать пароль с помощью pwgen, а потом пытаться его запомнить придумывая слова, начинающиеся на эти буквы... Фактически этот же способ используется в xkcdpass, но только вместо ввода первых букв фразы, мы вводим случаные слова

Аппаратное vs программное шифрование

SED — Self Encrypted Drives. Samsung EVO и PRO поддерживают аппаратное шифрование с использованием спецификации TCG OPAL 2.0. Фактически единственным вариантом программного шифрования в Linux является LUKS. Аппаратное и программное шифрование в общем и целом работают похожим образом и имеют свои достоинства и недостатки.

Почему Luks, а не аппаратное шифрование? — Диски с аппаратным шифрованием (SED) в 2018 году по заказу королевской полиции Нидерландов были взломаны, путем замены прошивки, в результате без пароля удалось получить доступ к данным. Этот трюк был проделан на старых SSD EVO 840 и EVO 850... Статья в журнале ксакеп. Новые диски вроде как избавлены от этих проблем, но это не точно и никто не гарантирует отсутствия аппаратных закладок, и никак не решается проблема с "быстрым переподключением" к другому устройству для считывания данных.

Другие недостатки аппаратного шифрования:

  • UEFI от некоторых производителей, например, ASUS и Acer, "забывают" загрузочные записи после перехода устройства в залоченное состояние... Acer не найдя загрузочных записей, начинает искать загрузчики по захардокоженным путям и первой грузит Windows...
  • sedutil не поддерживает спящий режим, поэтому потребуется пользоваться сторонней утилитой со всеми вытекающими рисками.
  • Ну и, конечно, мы не можем выбрать какой-то другой алгоритм шифрования кроме AES.

К сожалению программное шифрование намного медленее (где-то в 1.5-2x), потому как шифрование в самошифрующихся дисках осуществляется отдельным AES чипом (без поддержки AES-NI все еще печальнее). Однако, скорости записи не особо критична, потому как при просмотре видео с Youtube, тот же iostat -d показывает, что на диск пишется в среднем... 600кб/сек. При скачивании файлов из интернета мы ограничены скоростью соединения, которая явно меньше 3000Mb/s, а вот при копировании файлов скорость сначала будет высокой, а потом упадет из-за перенагрева чипа. Если для вас критична скорость записи...

Результаты моих тестов:

# Samsung SSD 980 500GB + Btrfs
$ dd if=/dev/zero of=testfile bs=64k count=128k conv=fdatasync oflag=direct
131072+0 records in
131072+0 records out
8589934592 bytes (8.6 GB, 8.0 GiB) copied, 7.26142 s, 1.2 GB/s

# WD Blue SN550 NVMe SSD, LUKS + Btrfs
$ dd if=/dev/zero of=testfile bs=64k count=128k conv=fdatasync oflag=direct 
131072+0 records in
131072+0 records out
8589934592 bytes (8.6 GB, 8.0 GiB) copied, 16.6447 s, 516 MB/s

Стоит упомянуть, что значительная часть SATA SSD поддерживает «установку пароля через BIOS», но выглядит это как ворота на замке без забора посреди чистого поля, так как эти пароли часто хранятся в открытом виде (наглядно), либо есть сервисный мастер пароль (см. тут)... и в конце-концов можно тупо перепаять контроллер. К шифрованию это не имеет никакого отношения.

IN SOVIET RUSSIA ИСПОЛЬЗОВАТЬ ШИФРОВАНИЕ ДАННЫХ НА ДИСКАХ НУЖНО ВСЕГДА ЧТОБЫ НЕ СЕСТЬ НА 🍾!

SED: самошифрующиеся диски

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

Сначала нужно скачать и записать на флешку live-образ.

Грузимся с live и далее все действия выполняем с него.

Установка пароля и запись PBA.

$ sedutil-cli --scan
Scanning for Opal compliant disks
/dev/nvme1  2  Samsung SSD 970 EVO 250GB                2B2QEXE7

# для того чтобы задать новый пароль (взамен заводского)
# нужно выполнить PSID Revert, так как будет сгенерирован новый ключ
# шифрования, но СТАРЫЕ ДАННЫЕ БУДУТ ФАКТИЧЕСКИ УТЕРЯНЫ
# PSID указан на наклейке SSD 
$ sedutil-cli --PSIDrever <PSID> /dev/nvme1n1

# задаем временный пароль
$ sedutil-cli --initialSetup p /dev/nvme1n1

На live уже есть PBA, который нужно записать на диск.

$ gunzip /usr/sedutil/UEFI64-1.15.1.img.gz 
$ sedutil-cli --loadPBAimage p /usr/sedutil/UEFI64-1.15.1.img /dev/nvme1n1

Включаем блокировку диска и запрос пароля после отключения питания:

$ sedutil-cli --enableLockingRange 0 p /dev/nvme1n1
$ sedutil-cli --setMBREnable on p /dev/nvme1n1  

Теперь можно поставить настоящий пароль:

$ sedutil-cli --setsidpassword p <your-password> /dev/nvme1n1
$ sedutil-cli --setadmin1pwd p <your-password> /dev/nvme1n1

PS: пароль администратора может отличаться от SID пароля

Для разблокировки:

$ sedutil-cli --disableLockingRange 0 <your-password> /dev/nvme1n1
$ sedutil-cli --setMBREnable off <your-password> /dev/nvme1n1  

Теперь можно вытащить флешку и выключить питание...

Примечание: в AUR есть sedutil-cli, установить его после завершения установки Arch Linux.

Ссылки:

Установка Arch Linux

Есть стандартная утилита для установки Arch Linux. Достаточно просто вбить arch-install в терминале, но лучше все слелать вручную, так как все нижеописанные действия предстоит проделывать не единожды.

Настройка WiFi

Если вы подключены от провода, то ничего настраивать не надо.

Для Wi-Fi нужно выполнить ряд действий:

$ iwctl

# Получим список сетевых интерфейсов
[iwd]# device list
                           Devices
-------------------------------------------------------------
  Name          Address          Powered    Adapter    Mode
-------------------------------------------------------------
  wlan0         ...              on         ...        ...

# Сначала просканируем сети
[iwd]# station <interface> scan

# А потом посмотрим все сети к которым можно подключиться
[iwd]# station <interface> get-networks
                               Available networks                             *
--------------------------------------------------------------------------------
    Network name                    Security          Signal
--------------------------------------------------------------------------------
    ...  
    <sid>                           psk               ****

# Подключаемся
[iwd]# station wlan0 connect <sid>

Проверка:

$ ping -c5 ya.ru

Синхронизация пакетов

Перед установкой желательно обновить базу пакетов и pgp-ключей для проверки подписи пакетов:

$ pacman -Sy archlinux-keyring

Разметка диска

Для Btrfs лучше всего подходит SSD.

Смотрим список и разделов и устройств:

fdsik -l

Пусть нам нужно поставить систему на nvme0n1.

Размечаем диск под систему, руководствуясь правилом от большего к меньшему:

cfdisk nvme0n1 

Должно получиться что-то типа этого:

раздел точка монтирования тип файловой системы размер описание
nvme0n1p1 / btrfs Весь объем минус размер efi/boot arch linux
nvme0n1p2 /boot vfat 512 MiB-1 GiB загрузочный раздел

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

Форматирование загрузочного раздела

Если у вас уже установлена Windows, пропускайте шаг с форматированием загрузочного раздела.

Форматируем загрузочный раздел:

mkfs.vfat -F32 -n ESP /dev/nvme0n1p2

Созданному разделу нужно выставить флаг boot, чтобы UEFI с него грузилось:

$ parted /dev/nvme0n1  
GNU Parted 3.5
Using /dev/nvme0n1
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p                                                                
...
 2      499GB   500GB  1074MB  fat32        Boot        msftdata

(parted) set 2 boot on                                                    
(parted) q                                                                
Information: You may need to update /etc/fstab.

Создание шифрованного раздела

Если ваш диск не поддерживает аппаратное шифрование либо оно вам не подходит по каким-то причинам...

Создаем шифрованный раздел:

cryptsetup -q -i 15000 luksFormat /dev/nvme0n1p1

С помощью --cipher можно указать алгоритм шифрования, если не устраивает дефолтный.

-i, --iter-time — это время в миллисекундах, которое требуется процессору на расшифровку ключа.

Производительность различных алгоритмов можно протестировать:

$ cryptsetup benchmark                                              
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1      2475976 iterations per second for 256-bit key
PBKDF2-sha256    4665521 iterations per second for 256-bit key
PBKDF2-sha512    1859177 iterations per second for 256-bit key
PBKDF2-ripemd160  972705 iterations per second for 256-bit key
PBKDF2-whirlpool  752206 iterations per second for 256-bit key
argon2i      11 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id     11 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
#     Algorithm |       Key |      Encryption |      Decryption
        aes-cbc        128b      1353.5 MiB/s      5450.8 MiB/s
    serpent-cbc        128b       124.9 MiB/s       918.1 MiB/s
    twofish-cbc        128b       247.8 MiB/s       468.1 MiB/s
        aes-cbc        256b      1009.3 MiB/s      4422.6 MiB/s
    serpent-cbc        256b       128.4 MiB/s       922.5 MiB/s
    twofish-cbc        256b       252.1 MiB/s       468.0 MiB/s
        aes-xts        256b      4542.7 MiB/s      4508.0 MiB/s
    serpent-xts        256b       787.7 MiB/s       802.5 MiB/s
    twofish-xts        256b       443.9 MiB/s       449.0 MiB/s
        aes-xts        512b      3688.6 MiB/s      3750.5 MiB/s
    serpent-xts        512b       826.0 MiB/s       812.8 MiB/s
    twofish-xts        512b       449.7 MiB/s       449.1 MiB/s

И открываем шифрованный раздел:

cryptsetup luksOpen /dev/nvme0n1p1 crypt

Последний аргумент это имя под под которым блочное устройство будет доступно в /dev/mapper.

Создание Btrfs

Создаем на шифрованном разделе файловую систему Btrfs:

mkfs.btrfs -n 32k -L arch ARCH_DEVICE

-n указываем размер узла дерева в котором хранятся данные. Чем он больше, тем лучше сжимается...

  • Тут и далее вместо ARCH_DEVICE указываем /dev/mapper/crypt при использовании LUKS либо просто /dev/nvme0n1p1.

Btrfs ‒ это одна из самых продвинутых файловых систем в Linux. Многие считают ZFS достойной альтернативой, но она не включена в ядро. Btrfs поддерживает механизм CoW (copy-on-write), создание снапшотов и сжатие данных... Снапшоты — это снимки файловой системы, точки для восстановления. Сжатие данных позволяет экономить место на диске, отказаться от использования архивов, но различные форматы изображений и видео и так поддерживают сжатие, поэтому оно не всегда полезно. За 4 года использования Btrfs я не сталкивался с какими-то критическими багами, и она меня не раз спасали от утраты данных. Простой пример: sudo rm -rf /<тут закрался пробел>.

В Btrfs нет привычных разделов, есть только подтома, которые можно сравнить с обычными каталогами. У них нет фиксированного размера, однако его можно ограничить с помощью quota. Снапшоты, если упускать некоторые детали, являются теми же самыми подтомами, те их можно монтировать и выполнять аналогичные операции.

Монтируем RootFS:

mount ARCH_DEVICE /mnt

Возможные сабвольюмы:

subvolume mount описание
@ / Корневой каталог (системные файлы)
@home /home Домашний каталог с пользовательскими данными. Нужен отдельный так как при откате системы к предыдущему состоянию очень важно сохранить существующий прогресс (куки браузера, конфиги, документы, файлы проектов и т.д.)
@snapshots /.snapshots Содержит снапшоты корня, которые создает snapper
@home.snapshots /home/.snapshots Содержит снапшоты хомяка, которые создает snapper
@machines /var/lib/machines Если не существует, то создаст systemd
@portables /var/lib/portables Если не существует, то создаст systemd
@docker /var/lib/docker Рекомендации самого Docker с их сайта
@docker_btrfs /var/lib/docker/btrfs Docker создает саьвольюмы по этому пути
@var_lib /var/lib Вместо создания @machines, @portables, @docker можно создать только этот, если в /var/lib не будет храниться чего-то важного (предполагается, что будут делаться снапшоты только корня и/или хомяка)
@var /var Аналогично выше описанному
@var_log или просто @log /var/log Логи как правило не представляют интереса, но в снапшотах занимают дополнительное место
@swap /swap или /var/swap, или /var/lib/swap Хранит файл подкачки. Должен монтироваться с nodatacow

Подтома @machines, @portables, @.snapshots, @home.snapshots и @docker (опционально при использовании docker) нужны чтобы не заморачиваться с переносом вложенных подтомов при замене старого подтома на снапшот. Однако, вся эта плоская структура подтомов скорее нужна на серверах. Чтобы не заморачиваться я словетую использовать Btrfs Asssistant.

Создаем нужные подтома:

btrfs sub create /mnt/@
btrfs sub create /mnt/@home

Отмонтируем RootFS:

umount /mnt

Монтируем подтома и загрузочный раздел:

mount -o compress=zstd:9,@ ARCH_DEVICE /mnt

# Примонтируем остальное
# x-mount.mkdir создает несуществующую директорию

# mount -o x-mount.mkdir /dev/nvme0n1p2 /mnt/boot

# Используем более закрытые права на каталог с
mkdir -m 700 /mnt/boot
mount BOOT_DEVICE /mnt/boot

mount -o x-mount.mkdir,compress=zstd:9,subvol=@home ARCH_DEVICE /mnt/home

Через двоеточие указывается уровень сжатия. Для десктопа лучшим является 9, обеспечивающий 15x максимальное сжатие. При нем скорость записи падает до 100 MiB/s, но при скачивании файлов из сети у нас скорость ~12 MiB/s (100 MBit/s)... Нам важна только скорость чтения, а она не падает меньше 2 GiB/s, те примерно равна скорость записи SSD (и не должна быть меньше нее в идеале). Протестировать уровни сжатия можно так:

$ zstd -T0 -b1 -e19
 1#Synthetic 50%     :  10000000 ->   3152996 (x3.172), 2539.0 MB/s, 2642.0 MB/s
 2#Synthetic 50%     :  10000000 ->   3129011 (x3.196), 1169.9 MB/s, 2647.2 MB/s
 3#Synthetic 50%     :  10000000 ->   3230491 (x3.096),  344.1 MB/s, 2115.2 MB/s
 4#Synthetic 50%     :  10000000 ->   3339961 (x2.994),  283.0 MB/s, 1899.2 MB/s
 5#Synthetic 50%     :  10000000 ->   3290137 (x3.039),  162.8 MB/s, 1788.2 MB/s
 6#Synthetic 50%     :  10000000 ->   3278503 (x3.050),  142.8 MB/s, 1823.8 MB/s
 7#Synthetic 50%     :  10000000 ->   3321448 (x3.011),  133.6 MB/s, 1696.6 MB/s
 8#Synthetic 50%     :  10000000 ->   3315141 (x3.016),  118.1 MB/s, 1696.1 MB/s
 9#Synthetic 50%     :  10000000 ->   3355994 (x2.980),   94.3 MB/s, 1573.8 MB/s
10#Synthetic 50%     :  10000000 ->   3363166 (x2.973),   68.0 MB/s, 1593.6 MB/s
11#Synthetic 50%     :  10000000 ->   3363170 (x2.973),   43.5 MB/s, 1590.3 MB/s
12#Synthetic 50%     :  10000000 ->   3362882 (x2.974),   36.2 MB/s, 1577.1 MB/s
13#Synthetic 50%     :  10000000 ->   3354692 (x2.981),   14.2 MB/s, 1610.2 MB/s
14#Synthetic 50%     :  10000000 ->   3354678 (x2.981),   15.0 MB/s, 1605.5 MB/s
15#Synthetic 50%     :  10000000 ->   3353801 (x2.982),   11.5 MB/s, 1597.6 MB/s
16#Synthetic 50%     :  10000000 ->   3080678 (x3.246),   10.3 MB/s, 2535.2 MB/s
17#Synthetic 50%     :  10000000 ->   3136878 (x3.188),   3.63 MB/s, 2184.5 MB/s
18#Synthetic 50%     :  10000000 ->   3145664 (x3.179),   3.73 MB/s, 2066.9 MB/s
19#Synthetic 50%     :  10000000 ->   3140424 (x3.184),   3.04 MB/s, 2101.9 MB/s

Установка системных пакетов

Установим ядро, драйвера и базовый набор пакетов:

pacstrap /mnt base base-devel linux linux-firmware linux-headers btrfs-progs cryptsetup efibootmgr ntfs-3g exfat-utils git micro terminus-font wget xorg zsh

Добавьте к этому списку xf86-video-amdgpu для видеокарт AMD или nvidia. А так же патчи безопасности для процессоров: amd-ucode или intel-ucode.

Генерация fstab

А теперь сгенерируем fstab, файл который содержит указания системы что и куда монтировать при загрузке:

genfstab -U /mnt | sed 's/,relatime/,noatime,commit=300,discard=async/' >> /mnt/etc/fstab

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

  • Каждый раз когда мы открываем файл, записывается время его изменения, noatime запрещает запись времени модификации файла.
  • Btrfs хранит кеш в оперативной памяти и сбрасывает его на диск через интервал указанный в секундах в параметреcommit.
  • discard=async предотвращает микрофризы при выполнении TRIM.

Первые два параметра продлевают ресурс SSD.

Вход в окружение chroot

Делаем chroot и "грузимся" в систему:

arch-chroot /mnt

Время и локаль

Редактируем /etc/locale.gen:

$ micro /etc/locale.gen

Нужно найти и расскоментировать (убрать в начале #) сл строки:

en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8

Генерируем локали:

$ locale-gen
Generating locales...
  ru_RU.UTF-8... done
  en_US.UTF-8... done
Generation complete.

Задаем локаль по-умолчанию:

localectl set-locale LANG=en_US.UTF-8
# системная локаль
echo LANG=en_US.UTF-8 > /etc/locale.conf
# или
locale > /etc/locale.conf

Смотрим список раскладок клавиатуры для консоли Linux (та в которую можно попасть, нажав Ctrl + Alt + F1-6):

localectl list-keymaps | grep ru

Загружаем раскладку:

loadkeys ruwin_ct_sh-UTF-8

Теперь мы можем по ctrl+shift переключать раскладку с английской на русскую.

Посмотрим шрифты для консоли:

ls /usr/share/kbd/consolefonts | less

Загрузим какой-нибудь шрифт с поддержкой кириллицы:

# 1080p
setfont ter-v14n
# 4k
setfont ter-v18b

Эти настройки нужно сохранить:

echo 'KEYMAP="ruwin_ct_sh-UTF-8"' >> /etc/vconsole.conf
 
# либо так
localectl set-keymap --no-convert ruwin_ct_sh-UTF-8

# И сохраняем шрифт
echo 'FONT="ter-v18n"' >> /etc/vconsole.conf

Ищем нужную временную зону:

$ timedatectl list-timezones | grep Mosc
Europe/Moscow

Задаем временную зону:

timedatectl set-timezone 'Europe/Moscow'

Включаем синхронизацию времени с NTP-сервером:

timedatectl set-ntp true

Опционально устанавливаем часы компьютера:

hwclock --systohc

Настройка имени хоста (машины)

В имени хоста можно использовать латинские символы, цифры, -, _, ....

В качестве имени хоста можно указать:

  • если у вас сервер, то доменное имя;
  • username-laptop или username-pc username-LaptopModel, username-archlinux или username-arch;
  • фамилию, кличку, звезду, планету... случайны набор символов;
  • не указывать его, оставив по умолчанию archlinux.

Имя хоcта нужно для вашей идентификации в локальной сети. Это имя можно использовать вместо локального ip-адреса, который может измениться. Например, вы можете через VPN подключиться к локальной сети в офисе, а далее через ssh your_hostname к своей машине...

hostnamectl set-hostname YOURHOSTNAME

Редактируем хосты:

micro /etc/hosts

Содержимое должно быть примерно таким:

127.0.0.1 l     ocalhost
::1             localhost
127.0.1.1       <YOUR_HOSTNAME>.localdomain <YOUR_HOSTNAME>
# строки ниже опциональны и приведены в примере из man
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

Initramfs

Linux грузится с помощью образа initramfs: сначала файловая система монтируется в оперативную память (Initial-RAM-File-System), загружаются драйвера, монтируется реальная файловая система, и наконец мы получаем возможность войти в систему.

Редактируем настройки образа в файле /etc/mkinitcpio.conf:

micro /etc/mkinitcpio.conf

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

# AMD
MODULES=(amdgpu)

# или NVIDIA
MODULES=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)

# или встройка AMD + дискретка NVIDIA
MODULES=(amdgpu nvidia nvidia_modeset nvidia_uvm nvidia_drm)

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

ВАЖНО!!!!!! В хуки добавляем btrfs и encrypt (при исп LUKS) до filesystems:

HOOKS=(... encrypt btrfs filesystems ...)

Хуки — это скрипты с функцией run_hook, которые выполняются последовательно при загрузке initrmafs.

Изменим дефолтный уровень сжатия для zstd:

# COMPRESSION_OPTIONS
# Additional options for the compressor
COMPRESSION_OPTIONS=(-T0 -15)

Теперь сгенериреум образ:

mkinitcpio -P

Добавление пользователя

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

useradd -m -G users -s /bin/zsh <YOUR_USERNAME>
  • -m ‒ создать каталог пользователя в /home;
  • -G ‒ дополнительные группы, передаваемые через запятую. Добавив себя в группу systemd-journal, вы сможете без sudo просматривать логи с помощью journalctl...

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

$ passwd <YOUR_USERNAME>
New password: 
Retype new password:
passwd: password updated successfully

В целях безопасности лочим пользователя root, чтобы из под него нельзя было авторизоваться:

$ passwd -l root
passwd: password changed.

Разрешаем sudo для себя (одноименной группы, создаваемой по умолчанию):

echo '%<YOUR_USERNAME> ALL=(ALL:ALL) ALL' > /etc/sudoers.d/<YOUR_USERNAME>

Так же можем отредактировать sudoers, разрешив пользователям в группе wheel доступ к sudo:

$ micro /etc/sudoers

# Нужно найти раскомментировать строку:
%wheel ALL=(ALL:ALL) ALL

Часто в инструкциях пользователя добавдяют в группу sudo. Группы wheel и sudo делают одно и то же: дают доступ к выполнению команды sudo. Так уж исторически сложилось, что в debian-based дистрибутивах используют группу sudo, а в RHEL ‒ wheel.

Загрузчик системы

Загружаться мы будем через systemd-boot. Для этого установим EFI:

bootctl install

Создаем загрузочную запись. Для начала сохраним PARTUUID шифрованного раздела в конфиг, так как его запомнить проблематично:

blkid -o value -s PARTUUID /dev/nvme0n1p2 > /boot/loader/entries/arch.conf

Отредактируем конфиг:

micro /boot/loader/entries/arch.conf

Он должен выглядеть примерно так:

title   Arch Linux
initrd  /amd-ucode.img
initrd  /initramfs-linux.img
linux   /vmlinuz-linux
options cryptdevice=PARTUUID=fa65a43e-eb75-48f0-aee1-975a50c2e00d:cryptroot:allow-discards root=/dev/mapper/cryptroot rootflags=subvol=/@ rw nvme_core.default_ps_max_latency_us=0

Последняя строчка, если не используется LUKS будет выглядеть так:

options root=PARTUUID=fa65a43e-eb75-48f0-aee1-975a50c2e00d rootflags=subvol=/@ rw nvme_core.default_ps_max_latency_us=0
  • Параметр nvme_core.default_ps_max_latency_us=0 нужен для некоторых моделей SSD M.2. Без него файловая система через неопределенное время переходит в read only.
  • initrd /amd-ucode.img - это подгрузка микрокодов процессора для исправления различных уязвимостей. /amd-ucode.img заменяем на /intel-ucode.img.

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

pacman -Sy amd-ucode
# либо
pacman -Sy intel-ucode

Настроим загрузчик:

micro /boot/loader/loader.conf
timeout 4
default arch.conf
console-mode max
editor no

Добавляем переменные окружения

/etc/environment — это лучшее место для задания переменных, которые будут установлены глобально для всех пользователей...

Сделаем редактором по-умолчанию micro для всех взамен старперского vim (мы его даже не стали устанавливать) из которого не могут выйти 95% пользователей Linux (<ESC>, :qa!, <Enter>).

echo 'EDITOR=micro' >> /etc/environment

Переменные окружения, которые должны быть доступны только для вас и приложений, запускаемых от вашего пользователя, в дальнейшем можно добавлять в ~/.zshenv, ~/.zlogin, ~/.xprofile, ~/.profile как export KEY=VALUE. Общие для всех переменные можно установить в сценариях /etc/profiles.d/<filename>.sh.

Если система стартует через systemd (со startx не будет работать), то пользовательские переменные окружения в виде KEY=VALUE можно установить в ~/.config/environments.d/<filename>.conf либо в /etc/environment.d/<filename>.conf (общие для всех).

Выбор графического окружения (DE)

Xfce или крыса

pacman -Sy xfce4 xfce4-goodies network-manager-applet lightdm lightdm-gtk-greeter
systemctl enable lightdm

Плюсы:

  • Выглядит минималистично... как Gnome 2, форком которого он и стал, но Gnome за это время уже сменил кучу версий Gtk.
  • Легковесность — пакеты занимают мало места, и система потребляет мало ресурсов. В xfce по умолчанию менее 900 пакетов в то время как для KDE или Gnome их нужно на треть больше...
  • Стабильность: разработчики что-то ломают нечасто.

Минусы:

  • Вытекают из стабильности: баги не исправляют годами. Например, тот же gnome-keyring, будет у вас упорно запрашивать пароль даже если для связки ключей вы установите тот же пароль, что и для пользователя (эта проблема решается именно так в Gnome).
  • Многие простые вещи, например, создание ярлыка на рабочем столе, требуют кучу дополнительных телодвижений (нужно создать Launcher, указать имя, выбрать исполняемый файл и иконку для него).
  • Трудность настройки.
  • Ограниченная поддержка HDPi.
  • Не поддерживает Wayland (тут сомнительный минус, так как последний скорее всего так никогда и не победит иксы).
  • Нет расширений как в Gnome, есть убогий аналог Plasmoid'ов.

Заключение: все так себе, но жить можно. Некоторые делают из Xfce конфетку, выбрасывая стандартные панели и пр.

Gnome

pacman -S gnome gnome-extra
systemctl enable gdm

Плюсы:

  • Закос под MacOS с довольно таки минималистичным интерфейсом;
  • Лучшая поддержка Wayland;
  • Сам Gnome ломается редко в отличии от расширений...

Минусы:

  • Без расширений не очень удобен в использовании.
  • Расширения ломаются после каждого обновления.
  • Нужно отдельно настраивать внешний вид для приложений под Qt, например, ч/з Kvantum.
  • Потребляет ресурсов не меньше чем Windows.

Заключение: не с проста во многих дистрибутивах является DE по умолчанию, например, в Ubuntu, Fedora, что говорит о доверии со стороны разработчиков дистрибутивов, подтверждает тезис о стабильной работе самой системы, но не сторонних расширений...

Plasma/KDE или просто кеды

pacman -S plasma kde-applications
systemctl enable sddm

Плюсы:

  • Похож на Windows 10.
  • Темы можно устанавливать глобально для Qt и Gtk приложений.
  • Настройка почти всего без ковыряния текстовых конфигов! Огромное количество настроек.

Минусы:

  • Постоянные баги.
  • С поддержкой Wayland проблемы.
  • Потребляет много ресурсов примерно как Gnome.

Заключение: поддержка Wayland обычным пользователям не нужна, а с большинством багов можно смириться + Steam Deck работает на KDE Plasma, а значит есть надежда, что баги будут исправляться быстрее, как и появляться новые фичи, так как Габен занесет денег...

Настройка сети [ на целевом хосте ]

Включим менеджер сети:

systemctl enable NetworkManager

Грузимся в систему

Можно не выходить, а выполнить что-то типа:

startx
systemctl start gdm
systemctl start sddm

Но если хочется проверить загрузку...

Выходим из chroot:

exit

Теперь можно перегрузиться и вытащить флешку:

reboot

Настройка системы

Управление пакетами

Для управления пакетами я советую использовать yay (yet another yaourt).

Главное преимущество Arch Linux в AUR, а поэтому нам нужен пакетный менеджер с его поддержкой. Раньше для этих целей использовали yaourt, но за прошедшие годы последний уступил пальму первенства.

$ cd /tmp
$ git clone https://aur.archlinux.org/yay-bin
$ cd yay-bin
$ makepkg -si

Настройка SWAP/ZRAM

Ядру Linux, независимо от размера оперативной памяти, нужно периодически сбрасывать страницы памяти в SWAP.

Для экономии ресурса SSD SWAP можно размещать в сжатом виде в оперативной памяти (ZRAM).

Установка:

$ yay -S zram-generator-git zram-generator-defaults

Включение ZRAM:

$ sudo systemctl restart systemd-zram-setup@zram0

Рекомендованные настройки SWAP для SSD:

/etc/sysctl.d/99-swappiness.conf

vm.swappiness=100
vm.vfs_cache_pressure=10

Применяем настройки:

$ sudo sysctl --system

Docker

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

$ yay -S docker docker-compose

# Добавим пользователя в группу docker, чтобы использовать команду docker без sudo
$ sudo usermod -aG docker $USER

# Перегрузимся
$ reboot

Юсаге:

# (Пере)собрать и запустить контейнеры
$ docker-compose up -d

# Остановить контейнеры
$ docker-compose stop

# Запустить остановленные ранее контейнеры
$ docker-compose start

# Остановить и удалить контейнеры
$ docker-compose down

docker-compose.yml:

version: '3.9'

services:
  postgres:
    container_name: postgres
    image: postgres:alpine
    env_file: .env
    networks:
      - internal
    ports:
      - '54320:5432'
    restart: unless-stopped
    volumes:
      - ./data/postgres:/var/lib/postgresql/data:rw

  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4
    depends_on:
      - postgres
    env_file: .env
    networks:
      - internal
    ports:
      - "5050:80"
    restart: unless-stopped
    volumes:
      - ./data/pgadmin:/var/lib/pgadmin:rw

  redis:
    container_name: redis
    image: redis:alpine
    networks:
      - internal
    ports:
      - "63790:6379"
    restart: unless-stopped
    volumes:
      - ./data/redis:/var/lib/redis:rw

networks:
  internal:

.env:

POSTGRES_USER=docker
POSTGRES_PASSWORD=password
POSTGRES_DB=db
PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.org
PGADMIN_DEFAULT_PASSWORD=admin

В pgadmin заходим через localhost:5050, в качестве имени хоста базы указываем имя сервиса, те postgres вместо традиционного localhost и порт 54320,

Snapper

Snapper ‒ это менеджер снапшотов (снимков состояния файловой системы) для Btrfs. Он может их создавать/удалять по таймеру, а так же позволяет восстанавливать отдельные файлы.

$ yay -Sy snapper

Установим так же хук, который будет делать снапшоты после каждого обновления пакетов:

$ yay -S snap-pac

Снапшоты делаются каждый час, если не переопределить это поведение:

$ systemctl edit snapper-timeline.timer

[Timer]
OnCalendar=<period>

Настройки по-умолчанию предполагают слишком длительное хранение снапшотов, что может привести к постоянной проблеме нехватки места, если у вас SSD маленького объема.

Создаем новый шаблон файла конфигураций, чтобы не редактировать дефолтный:

$ cd /usr/share/snapper/config-templates
$ cp default config
$ micro config

Где значения TIMELINE_LIMIT_<PRERIOD> указывают сколько хранить N последних снапшотов за час (HOURLY)/день (DAILY)/неделю (WEEKLY)/месяц (MONTHLY)/год (YEARLY).

Пример конфига:

...
TIMELINE_LIMIT_HOURLY="10"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="0"
TIMELINE_LIMIT_MONTHLY="0"
TIMELINE_LIMIT_YEARLY="0"
...

Храним 10 последних за час и 7 ежедневных (хранится самый первый за день).

snapper -c root create-config -t config /
snapper -c home create-config -t config /home
systemctl enable snapper-timeline.timer
systemctl enable snapper-cleanup.timer

Восстановление удаленного файла

# Смотрим номер последнего снапшота
sudo snapper -c <config> list -a

# Восстанавливаем файл
sudo snapper -c <config> undochange 0..<number> /path/to/file

Заменяем корневой сабвольюм на снапшот

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

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

$ sudo su

$ mount /dev/mapper/root /mnt

$ ls /mnt 
@ @home @.snapshots ...

$ cd /mnt

# Смотрим снапшоты
$ ls @.snaphosts
... 42 ...

# Переименовываем старый корневой сабвольюм
$ mv @ @old

# Помним, что snapshot и subvolume это одно и тоже, считай, а значит мы монтировать снапшот 
# Делаем снимок снапшота, по-сути копирем его, так как снапшоты, создаваемые snapper readonly
$ btrfs sub snap @.snaphots/42/snapshot @

# Редактируем fstab, если он содержит subvolid
# Ищем `subvol=/@` и удаляем `subvolid=N,`
$ micro @/etc/fstab

# Или же можно прописать subvolid
$ sudo btrfs sub show @ | grep 'Subvolume ID'
        Subvolume ID:           XXX

# Монтируем сабвольюм
$ mount -o remount /

# Теперь можно удалить @old
$ btrfs su de @old

GUI

image

Это стандартная утилита для дистрибутива Garuda Linux (основан на Arch'е как Manjaro и пр. суррогаты). Графический менеджер для управления снапшотами и восстановления из них.

yay -S btrfs-assistant btrfsmaintenance

Для использования Btrfs Assistant не подходит плоская схема, при которой подтома со снапшотами (@snapshots, @home.snapshots и тп) монтируются в /.snapshots или /home/.snapshots. При восстановлении из снапшота, делает снапшот савольюма, а затем заменяет его на выбранный снапшот, все дочерние сабвольюмы и снапшоты перемещаются.

Установка пакетов

Все пакеты стараемся ставить через yay. Flatpak используем только в крайних случаях: а) если пакета нет в репозитории, б) он сломался и не работает. Идея, конечно, хороша, но VS Code из Flatpak не юзабелен, а в каком-нибудь Brave не возможно подключиться к Tor. Бинарники из pip/npm можно ставить с помощью pipx/npx.

Flatpak

Графические приложения можно устанавливать через Flatpak. Приложения запускаются в изолированной среде, и они не имеют права на запись в системные каталоги хоста. Принцип работы схож с Docker. Если кратко: мы запускаем приложение в виртуалке на основе LXC(прим. контейнерезация — это разновидность виртуализации). По идее оно не может повредить систему, так как внутри Flatpak контейнера нельзя использовать sudo, но украсть данные это не помешает личные данные из хомяка...

yay -S flatpak
flatpak install -y Krita 

Плюсы:

  • Безопасность: приложения запускаются в контейнерах и имеют ограниченный доступ к файловой системе. Так же можно, например, ограничить доступ к сети.
  • Частичные, так называемые дельта-обновление - не нужно скачивать пакет целиком, так как исп. ostree , работающий по тому же принципу, что и git, те при обновлении скачиваются только различия между версиями.
  • Не нужна настройка, например, шрифтов как в Telegram и тд.
  • Зависимости идут в виде отдельных рантаймов, общих для других приложений в отличие от AppImage, где все-все зависимости идут с приложением.
  • Решает проблему с устаревшими зависимостями после обновления системы.

Минусы:

  • Приложения запускаются дольше (не мгновенно).
  • Занимают дополнительное место за счет рантаймов. Например одновременно могу стоять две версии org.gnome.Platform и три org.kde.Platform.
  • Нельзя доставить зависимости, например, те которые видим в выводе yay -Qi. Проблема со шрифтами.
  • Не работает интеграция с Gnome, KDE у того же Chromium.
  • Невозможно полноценно использовать IDE, установленные через Flatpak из-за его ограничений. В качестве решения этой проблемы авторы советуют использовать Sdk.Extension. Например, flatpak install flathub org.freedesktop.Sdk.Extension.golang и запуск среды разработки FLATPAK_ENABLE_SDK_EXT=golang flatpak run com.visualstudio.code.
  • В Telegram нельзя перетащить файл для отправки, если он где-то в /mnt.
  • Приложения в репозитории часто требуют больше прав чем им необходимо для работы.

Topgrade

Обновляет все подряд: пакеты pacman, AUR, Flatpak... образы Docker, плагины для ZSH и тд

$ yay -S topgrade
$ topgrade

Дополнения

Добавление загрузочной записи

Linux

# Загрузочный раздел: /dev/nvme0n1p4
# EFI не удалено
efibootmgr -c -d /dev/nvme0n1 -p 4 -L "Linux Boot Manager" -l '\efi\boot\bootx64.efi'

# Удаление записи
efibootmgr -b 000X -B

# Список записей, порядок загрузки и тп
efibootmgr -v

# Смена порядка. См вывод предыдущей команды
efibootmgr -o 0002,0001,...

Windows

Проблема: после установки/обновления Windows пропадает загрузочная запись Linux.

Запускаем терминал (Windows Terminal) от имени администратора (Win+X, Alt+A) и выполняем:

PS C:\Users\yourname> bcdedit /copy '{bootmgr}' /d "Arch Linux Boot"
The entry was successfully copied to {6c4580c1-e401-11ec-b643-089798e96d74}.
PS C:\Users\yourname> bcdedit /set '{6c4580c1-e401-11ec-b643-089798e96d74}' path \efi\boot\bootx64.efi
The operation completed successfully.
PS C:\Users\yourname> bcdedit /set '{fwbootmgr}' displayorder '{6c4580c1-e401-11ec-b643-089798e96d74}' /addfirst
The operation completed successfully.
PS C:\Users\yourname>

Восстановление Windows EFI (после удаления)

Скачайте образ Windows с сайта Microsoft.

Если у вас есть флешка с Ventoi и Windows, то пропускаем запись загрузочной флешки.

Установите утилиту для создания загрузочных флешек для Windows:

$ yay -S woeusb

Записываем образ:

$ sudo woeusb --device ~/Downloads/Windows...iso /dev/sdX

Теперь нам нужно загрузиться с флешки с Windows, проделав операции по смене приоритетов...

Либо можно почитать man efibootmgr.

Грузимся с флешки, ожидаем пока закончится загрузка Windows и нажимаем Shift + F10. Откроется консоль.

В консоли выполняем следующее:

> diskpart
DISKPART> list volume
:: Смотрим, где у нас установлена Windows
:: Если вы установили, Arch Linux на другой диск, то удалите загрузочный раздел винды (но не сам раздел с Windows! см. `help`)
DISKPART> exit

:: Устанавливаем Windows EFI на загрузочный раздел
> bcdboot c:\windows

Создаем RAID-1

SSD не живут вечно, у них есть ресурс перезаписи, который в зависимости от типа памяти (SLC, MLC, TLC или QLC, где первая буква количтсво бит на ячейку 1-4) может составлять от 10000 до 2500 перезаписей ячеек. Но очень часто SDD умирают, даже не выработав его. К этому приводит неожиданная смерть контроллера. Смерть контроллера означает невозможность восстановлкения данных! Поэтому, если на вашем диске хранится что-то важное, что нельзя беекапить в облако, то лучше докупить диск и запихнуть его в зеркальный RAID.

# Создаем raid
# Используем flag --metadata=1.0, чтобы супер-блок располагался в конце диска
mdadm -v --create --metadata=1.0 /dev/md0 -l 1 -n 2 missing /dev/nvme1n1p1

# Создаем файловую систему на /dev/md0 и тп

# Монтируем созданный raid
mount ... /dev/md0 /mnt

# Копируем данные с раздела /dev/nvme0n1p1 помощью rsync'a
rsync -avh ... /mnt

# Добавляем его в массив
mdadm --add /dev/md0 /dev/nvme0n1p1

# Ждем пока данные синхронизируются
watch -n 1 /proc/mdstat

# Сохраняем конфиг
mdadm --verbose --detail --scan >> /etc/mdadm.conf

Хуки /etc/mkinitcpio.conf:

HOOKS=(base systemd autodetect modconf kms keyboard sd-vconsole block mdadm_udev sd-encrypt filesystems fsck)

mdadm_udev

У меня используется RAID-1 > LUKS > Btrfs.

options md=0,/dev/nvme0n1p1,/dev/nvme1n1p1 rd.luks.name=f2233ed8-fbe6-4199-890a-d416c7a2a62b=root root=/dev/mapper/root rootflags=rw,subvol=@
sudo mdadm --misc --detail /dev/md0

/dev/md0:
           Version : 1.2
     Creation Time : Wed Oct 25 00:17:13 2023
        Raid Level : raid1
        Array Size : 487455744 (464.87 GiB 499.15 GB)
     Used Dev Size : 487455744 (464.87 GiB 499.15 GB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

     Intent Bitmap : Internal

       Update Time : Fri Oct 27 04:30:48 2023
             State : clean 
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : bitmap

              Name : sergey-arch:0  (local to host sergey-arch)
              UUID : 17332b2d:1685f236:6e28b36e:277f39cf
            Events : 20482

    Number   Major   Minor   RaidDevice State
       0     259        3        0      active sync   /dev/nvme1n1p1
       1     259        6        1      active sync   /dev/nvme0n1p1
@s3rgeym
Copy link
Author

s3rgeym commented Aug 2, 2020

Gnome: Переключение раскладки по Alt+Shift

Запускаем dconf-editor и переходим в /org/gnome/desktop/input-sources/xkb-options:

Custom value:

['grp:alt_shift_toggle', 'lv3:ralt_switch']

'lv3:ralt_switch' сам добавляется постоянно.

@s3rgeym
Copy link
Author

s3rgeym commented Aug 3, 2020

cPanel работа через SSH

image

  1. Можно загрузить свой публичный ключ и авторизовать через веб-интерфейс.
ssh-keygen -t rsa -b 4096 -C email
  1. Генерируем ключ через веб-интефрейс, авторизуем его, а затем скачиваем приватный ключ.

Далее:

$ mv xxx_rsa ~/.ssh
$ cd ~/.ssh
$ chmod 600 xxx_rsa
$ ssh-add xxx_rsa
Enter passphrase for xxx_rsa: 
Identity added: xxx_rsa (xxx_rsa)

@s3rgeym
Copy link
Author

s3rgeym commented Aug 11, 2020

Заменяем GDM на Lightdm

$ yay -S lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings

Edit /etc/lightdm/lightdm.conf:

[Seat:*]
# ...
greeter-session=lightdm-gtk-greeter

Настроить lightdm можно через графический интерфейс либо путем редактирования /etc/lightdm/lightdm-gtk-greeter.conf.

$ sudo systemctl disable gdm
$ sudo systemctl enable lightdm
Так как блокировка экрана работает через gdm, то нужно поставить пакет `gnome-screensaver` и добавить его в автозагрузку:
$ yay -S gnome-screensaver
$ sudo ln -sf /usr/share/applications/gnome-screensaver.desktop /etc/xdg/autostart

Вешаем dm-tool lock на сочетание клавиш Super + L.

Обои лучше копировать в /usr/share/pixmaps/, так как у lightdm нет прав на чтение домашнего каталога:

# лучше использовать универсальное имя wallpaper.jpg чтобы каждый раз не править настройки
$ sudo cp /path/to/image.jpg /usr/share/pixmaps/wallpaper.jpg

TODO: написать про настройки языка ввода при lockscreen.

@s3rgeym
Copy link
Author

s3rgeym commented Aug 15, 2020

Neofetch: show DE version

sed -ri 's/(de_version=")[^"]+/\1on/' ~/.config/neofetch/config.conf

@s3rgeym
Copy link
Author

s3rgeym commented Aug 16, 2020

Gnome: слишком большой размер интефейса в Qt-приложениях

Проблемы, связанные с масштабированием в Qt.

$ sudoedit /etc/environment
QT_AUTO_SCREEN_SCALE_FACTOR=0
QT_SCREEN_SCALE_FACTORS=2
QT_SCALE_FACTOR=1

@s3rgeym
Copy link
Author

s3rgeym commented Aug 18, 2020

Использование Python

В Arch Linux по-умолчанию pip не установлен. Чем он плох? ‒ Он не умеет
управлять зависимостями. У пакетов обычно имеется куча зависимостей, и когда мы удаляем
родительский пакет через pip uninstall, зависимости остаются, поэтому пакеты для
Python предпочтительнее ставить через yay. Так же я настоятельно рекомендую
использовать asdf-vm либо pyenv для управления версиями Python. Для запуска
исполняемых файлов, которые содержат python-пакеты, можно использовать pipx,
который создает виртуальное окружение и устанавливает в него пакет.

@s3rgeym
Copy link
Author

s3rgeym commented Aug 18, 2020

Vim Cheats

Command Desc
gf Open file at cursor position. Use ^o to go back.

@s3rgeym
Copy link
Author

s3rgeym commented Aug 20, 2020

Bitcoin

Package Description
bitcoin-qt GUI
bitcoin-cli CLI Tool
bitcoin-daemon Contains bitcoind service

Запустить сервис (нужен для bitcoin-cli):

$ sudo systemctl enable --now bitcoind

!Конфликтует с Bitcoin Core (не запускается, когда запущен bitcoind).

Сохраняем данные на другое устройство:

$ mkdir /mnt/hdd/Bitcoin
$ ln -s /mnt/hdd/Bitcoin ~/.bitcoin

Для сервиса bitcoind:

$ sudo systemctl edit bitcoind
# /etc/systemd/system/bitcoind.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/bitcoind -daemon -pid=/run/bitcoind/bitcoind.pid -conf=/mnt/hdd/Bitcoin/bitcoin.conf -datadir=/mnt/hdd/Bitcoin

Используйте флаг -prune чтобы не выкачивать базу транзацкий полностью (340 гигабайт по состоянию на середину августа 2020).

Изменяем desktop entry для Bitcoin Core:

$ cp /usr/share/applications/bitcoin-qt.desktop ~/.local/share/applications
$ vim ~/.local/share/applications/bitcoin-qt.desktop
# ищем
Exec=bitcoin-qt %u
# и заменяем на
Exec=bitcoin-qt -prune=1000 %u

@s3rgeym
Copy link
Author

s3rgeym commented Aug 21, 2020

Изменяем аргументы приложения, запускаемого через ярлык

$ cp /usr/share/applications/application.desktop ~/.local/share/applications
$ vim ~/.local/share/applications/application.desktop

@s3rgeym
Copy link
Author

s3rgeym commented Aug 23, 2020

Поддержка иероглифов пиздоглазиков

普京是个混蛋

$ yay -S noto-fonts-cjk

@s3rgeym
Copy link
Author

s3rgeym commented Aug 24, 2020

Too many open files

# все лимиты
$ ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         unlimited
-m: resident set size (kbytes)      unlimited
-u: processes                       128173
-n: file descriptors                1024
-l: locked-in-memory size (kbytes)  1024
-v: address space (kbytes)          unlimited
-x: file locks                      unlimited
-i: pending signals                 128173
-q: bytes in POSIX msg queues       819200
-e: max nice                        0
-r: max rt priority                 0
-N 15:                              unlimited
# открытые файлы
$ ulimit -n
1000

Прописываем в /etc/security/limits.conf.

%username% - nofile 65536

Вместо %username% можно указать *.

Временное решение:

$ ulimit -n 65536

@s3rgeym
Copy link
Author

s3rgeym commented Aug 25, 2020

image

XDG User Directories

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

См. ~/.config/user-dirs.dirs.

$ xdg-user-dir TEMPLATES

$ xdg-user-dirs-update --set MUSIC "/mnt/raid0/Music"

Это некий стандарт, который разрабочики вольны реализовывть как им вздумается:

${XDG_CACHE_DIR:-$HOME/.cache}

@s3rgeym
Copy link
Author

s3rgeym commented Sep 12, 2020

Tilix ‒ тайловый терминал для Gnome

#  Нужен для добавления "Open Tilix Here" в контекстное меню nautilus
$ yay -S python-nautilus

$ yay -S tilix

# Создаем каталог для тем
$ mkdir -p ~/.config/tilix/schemes

@s3rgeym
Copy link
Author

s3rgeym commented Nov 4, 2020

Jupyter Notebook/Lab

В Юпитере работать удобнее чем в терминале. Он может рисовать графики прямо в консоли. Де-факто стандарт в мире датасасенса (потому что в курсах учат пользоваться именно им).

Установка:

$ yay -S jupyterlab

Запуск:

$ jupyer-lab

Shift + Right Mouse Click вызов браузерного меню.

Как использовать виртуальные окружения?

Для этого нужно создать виртуальное окружение и установить в него Юпитер:

~
❯ python -m venv ~/venvs/myenv                        

❯ . ~/venvs/myenv/bin/activate

~
myenv ❯ pip install --upgrade pip
Collecting pip
  Downloading pip-20.2.4-py2.py3-none-any.whl (1.5 MB)
     |████████████████████████████████| 1.5 MB 973 kB/s 
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 20.2.3
    Uninstalling pip-20.2.3:
      Successfully uninstalled pip-20.2.3
Successfully installed pip-20.2.4

~
myenv ❯ pip install jupyter          
Collecting jupyter
  Downloading jupyter-1.0.0-py2.py3-none-any.whl (2.7 kB)
  ...

~
myenv ❯ python -m ipykernel install --user --name myenv
Installed kernelspec myenv in /home/sergey/.local/share/jupyter/kernels/myenv

~
myenv ❯ cat ~/.local/share/jupyter/kernels/myenv/kernel.json
{
 "argv": [
  "/home/sergey/venvs/myenv/bin/python",
  "-m",
  "ipykernel_launcher",
  "-f",
  "{connection_file}"
 ],
 "display_name": "myenv",
 "language": "python"
}%

Далее мы ставим в это окружение все необходимые в работе модули.

При создании нового Notebook в списке Select Kernel выбираем Start Other Kernel myenv.

Для удаления:

~
❯ rm -rf ~/venvs/myenv

~
❯ jupyter kernelspec remove myenv

Все ядра:

~
❯ jupyter kernelspec list 
Available kernels:
  python3    /usr/share/jupyter/kernels/python3

@s3rgeym
Copy link
Author

s3rgeym commented Jan 15, 2021

Git: считаем количество добавленных/удаленных строк за период

~/.local/bin/git-stat-sum:

git log --numstat --format="" "$@" | awk '{files += 1}{ins += $1}{del += $2} END{print "total: "files" files, "ins" insertions(+) "del" deletions(-)"}'
chmod +x ~/.local/bin/git-stat-sum 

add to ~/.gitconfig

[alias]
  summary = !git-stat-sum \"$@\"
❯ git summary --since=2020-01-01    
total: 1255 files, 19421 insertions(+) 4623 deletions(-)

@s3rgeym
Copy link
Author

s3rgeym commented Feb 4, 2021

https://gist.github.com/tz4678/bd33f94ab96c96bc6719035fcac2b807#%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D0%BC-%D1%8F%D0%B4%D1%80%D0%BE-%D0%BD%D0%B0-%D1%81%D1%82%D0%B0%D0%B1%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5

Пакет linux-headers-lts сейчас называется linux-lts-headers

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

@s3rgeym
Copy link
Author

s3rgeym commented Feb 18, 2021

Антимусор

$ rm -rf ~/.cache/thumbnails

@s3rgeym
Copy link
Author

s3rgeym commented Mar 20, 2021

Я сюда больше ничего не добавляю. Поднял локальную вики.

@s3rgeym
Copy link
Author

s3rgeym commented Jun 4, 2021

SEDUTIL

Дано: SED и Dual Boot.
Проблема: после разблокировки сразу грузится Windows, пропадает запись "Linux Boot Loader" в меню UEFI.
Где наблюдается: ноутбуки от Acer c каким-то убогим UEFI.

Временное решение:

$ mv /boot/EFI/Microsoft /boot/EFI/MS

Для того чтобы Windows можно было выбрать из меню systemd-boot, добавляем файл /boot/loader/entries/windows.conf:

title Windows Boot Manager
efi   \EFI\MS\Boot\Bootmgfw.efi

@s3rgeym
Copy link
Author

s3rgeym commented Jun 5, 2021

Создаем шифрованные разделы с помощью LUKS

# Создаем пустой файл
$ touch encrypted-vol   

# В случае использования BTRFS нужно отключить copy-on-write и сжатие
$ chattr +C encrypted-vol
$ sudo btrfs property set encrypted-vol compression ""

# Данная команда резервируетместо для файла, при этом данные на диск не записываются
$ fallocate -l 30G encrypted-vol

# Создаем шифрованный раздел и задаем пароль
$ cryptsetup -v luksFormat encrypted-vol

WARNING!
========
This will overwrite data on encrypted irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for encrypted-vol: 
Verify passphrase: 
Key slot 0 created.

# Открываем раздел, последним аргументом указываем имя виртуального устройства в /dev/mapper
$ sudo cryptsetup -v luksOpen encrypted-vol encrypted
[sudo] password for archuser: 
Enter passphrase for encrypted-vol: 
Key slot 0 unlocked.
Command successful.

# Теперь создадим файловую систему для раздела
$ sudo mkfs.ext4 /dev/mapper/encrypted
mke2fs 1.46.2 (28-Feb-2021)
Creating filesystem with 7860224 4k blocks and 1966080 inodes
Filesystem UUID: 11109d87-c5f0-452f-bb98-fae3f6611668
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

# Создадим точку монтирования
$ sudo mkdir /mnt/encrypted

# Смонтируем
$ sudo mount /dev/mapper/encrypted /mnt/encrypted

# Пофиксим права
$ sudo chown -R $USER:$USER /mnt/encrypted

@s3rgeym
Copy link
Author

s3rgeym commented Jun 7, 2021

Копирование подразделов BTRFS

# Отправить можно только read-only volume
$  btrfs su sn -r /mnt/src/@ /mnt/src/@_ro

# Копируем (вложенные снапшоты скопированы не будут)
$ btrfs send /mnt/src/@_ro | btrfs rec /mnt/dst

# Меняем имя на оригинальное
$ mv /mnt/dst/@_ro /mnt/dst/@

# Делаем subvolume доступным для записи
$ btrfs property set -ts /mnt/dst/@ ro false

@s3rgeym
Copy link
Author

s3rgeym commented Jun 9, 2021

~/workspace/dev-stack 
❯ docker-compose exec postgres psql -U postgres
psql (13.3)
Type "help" for help.

postgres=# create user wikijs with password 'wikijsrocks';
CREATE ROLE
postgres=# create database wiki with owner wikijs;
CREATE DATABASE
postgres=# grant all privileges on database "wiki" to wikijs;
GRANT
postgres=# \q

@s3rgeym
Copy link
Author

s3rgeym commented Jun 9, 2021

Sort Favorite Apps By Name

~ 
❯ dconf write '/org/gnome/shell/favorite-apps' "$(dconf read '/org/gnome/shell/favorite-apps' | python -c 'import ast,sys; print(sorted(ast.literal_eval(sys.stdin.read())))')"

@s3rgeym
Copy link
Author

s3rgeym commented Aug 19, 2021

~ via ⬢ v16.6.2 on ☁️ tz4678@gmail.com 
λ sudo lsblk /dev/nvme0n1p2 
NAME      MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
nvme0n1p2 259:4    0  300G  0 part  
└─crypt   254:0    0  300G  0 crypt /mnt/rootfs
                                    /var/lib/docker/btrfs
                                    /home/.snapshots
                                    /var
                                    /home
                                    /.snapshots
                                    /

@s3rgeym
Copy link
Author

s3rgeym commented Oct 21, 2021

image

@s3rgeym
Copy link
Author

s3rgeym commented Nov 26, 2021

Борьба со взбесившимся логированием:

~ 
➜ cat /etc/systemd/journald.conf.d/*.conf
[Journal]
MaxLevelStore=warning
[Journal]
SystemMaxUse=50M
SystemMaxFileSize=10M

@s3rgeym
Copy link
Author

s3rgeym commented May 13, 2022

LVM on LUKS

Я пришел к выводу, что не имеет смысла, так как swap не нужен при использовании zram.

Создадим логические разделы:

$ lvm vgcreate vg_root /dev/mapper/crypt
  Volume group "vg_root" successfully created

# Размер под swap=RAM, но можно сделать его и меньше. 
# Система успешно входит в гибернацию, если количество занятой оперативно памяти меньше размера раздела гибернации.
$ lvm lvcreate -L 32G --name lv_swap vg_root       
  Logical volume "lv_swap" created.

# Тут будет система
$ lvm lvcreate -L 100%FREE --name lv_arch vg_root        
  Logical volume "lv_arch" created.

Создади swap и включим его:

$ mkswap -L swap /dev/vg_root/lv_swap
Setting up swapspace version 1, size = 32 GiB (34359734272 bytes)
LABEL=swap, UUID=7cc5bf84-2328-4dad-a0a7-cad7db249ad4

$ swapon /dev/vg_root/lv_swap

LUKS on LVM

Это уже более жизнеспособный юзекейс: у нас кончается место на диске, мы подключаем новый, добавляем его в volume group, а затем увеличиваем логический раздел так чтобы он занял все место.

@s3rgeym
Copy link
Author

s3rgeym commented Jun 1, 2022

Старое

Дополнения

Касательно необходимости заведения отдельного сабвольюма для /var, на самом деле перенос тех вложенных сабволбюмов, создаваемых докером не сложен:

cd /mnt/rootfs/@oldroot/var/lib/docker/btrfs/subvolumes
for i in *; do btrfs sub snap $i /var/lib/docker/btrfs/subvolumes/$i; done
  • Предполается, что новый корень смонтирован в /;
  • Вместо создания снапшота, можно переместить сабвольюмы с помощью mv.

>>> Установщик Arch Linux (устарел и годится только как пример для написания своего) <<<

Table of Contents

Установка Arch Linux

Arch Linux

Arch Linux ‒ это один из немногих дистрибутивов Linux, использующих модель роллинг-релизов. Это означает, что в нем доступны самые последние версии пакетов. Это одновременно является его как преимуществом так и недостатком. Пересесть на него меня заставила необходимость: мое компьютерное железо (процессор ryzen 5 2600 и видеоадаптер rx 590) оказались не совместимы с версией Linux Kernel младше 4.20.

image

На самом деле все не так плохо, но неприятные инциденты имеют место хотя и очень редко.

Создание образа

Качаем образ и записываем его с помощью команды:

$ sudo dd if=/path/to/iso of=/dev/sdX bs=8M status=progress; sync

Где sdX – имя нашего USB устройства. Перегружаемся после удачного завершения операции.

В Windows для создания загрузочной флешки можно использовать Rufus.

image

Изменяем приоритет загрузки в BIOS/UEFI

При загрузке системы нажимаем F2 или Del (зависит от производителя материнской платы). Во вкладке BIOS в приоритете загрузки делаем первым наше USB-устройство. Нажимаем F10 и сохраняем настройки. На материнках ASUS нужно CSM (режим поддержки устаревших операционных систем) установить в auto.

Начало установки

Инструкцию по установке Arch Linux можно посмотреть так:

less ~/install.txt

Небольшой лайфхак: во время установки можно переключаться между терминалами с помощью Ctrl+Alt+F1..6. Если мы нажмем Ctrl+Alt+F2 откроется второй терминал (по-умолчанию мы работаем в первом) и потребуется ввести пароль root, во втором терминале мы можем открыть инструкцию и периодически подсматривать ее, переключаясь между терминалами.

Настройка сети

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

rfkill unblock wifi
wifi-menu

Следует отметить, что не все usb wifi адаптеры гараниторованно поддерживаются. Например, у меня не захотел работать dexp wfa 301, а вот с tp-link все ок.

Проверить соединение можно с помощью команды ping:

$ ping -c 3 ya.ru
PING ya.ru (87.250.250.242) 56(84) bytes of data.
64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=53 time=12.1 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=2 ttl=53 time=12.1 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=3 ttl=53 time=12.1 ms

--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 5ms
rtt min/avg/max/mdev = 12.137/12.139/12.141/0.127 ms

Выбор файловой системы

Файловая система Btrfs может размещаться на одном и более устройствах/разделах. В Btrfs есть подтома с динамическим размером (по-сути ‒ обычные каталоги) и группы с помощью которых можно ограничивать размер подтомов. Главная фишка Btrfs ‒ это легковесные снапшоты и на диске хранятся только различия между оригиналом и накопленные изменения. Мы можем периодически делать снапшоты подтомов, а потом в случае необходимости восстанавливать состояние системы, причем делать это налету.

Касательно LVM: единственное удобство в нем для меня – это возможность динамически менять размер разделов. Самая частая проблема, которая у меня была раньше – это то, что я не угадывал размер для корня. Мы можем добавлять в группу другие разделы (не обязательно на одном устройстве) и устройства. Нет ограничений как для обычных разделов, когда невозможно расширить раздел за счет предыдущего, нам вообще об этом не нужно заботиться. В LVM есть группы разделов и логические разделы. У логических разделов свои файловые системы. Увеличение размера логического раздела в отличии от уменьшения размонтирования не требует. resize2fs в LVM работает заметно быстрее. В LVM так же есть снапшоты, но они по-сути представляют полный бекап раздела.

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

Размечаем диск

Для начала посмотрим все доступные устройства:

fdisk -l

Создадим новый раздел:

# fdisk /dev/nvme0n1
# Более удобная утилита чем fdisk, в ней можно выбирать все стрелочками
cfdisk /dev/nvme0n1
# При разметке swap размещайте после home, т.е. самым последним на случай, если потребуется увеличить его размер

Если есть раздел с Windows сделайте от него отступ 1-2 MB, т.к. Windows выходит за установленные лимиты и портит соседние разделы.

Если не установлен Windows:

Создаем раздел в FAT-32 размером, а затем форматируем его:

mkfs.fat -F32 -n ESP /dev/nvme0n1p1

Для FAT32 https://en.wikipedia.org/wiki/File_Allocation_Table#Size_limits на минимальный размер раздела составляет от 32 до 260 мегабайт в зависимости от размера логического сектора. У современных SSD размер блока составляет 512 bytes, что дает минимальный размер ESP 32 MiB. Для Windows 10 минимально-рекомендованным является размер в 100MiB, при этом будет занято 25% раздела. Для Dual Boot под каждую ОС можно выделить по 100 MiB (200 MiB в совокупности). Arch Wiki рекомендует 512 MiB.

Немного про swap: в Linux есть компонент ядра OOM-killer (Out-of-Memory), который запускается когда кончается доступная память, тогда он убивает наименее приоритетные процессы, например, может убить IDE с несохраненным прогрессом. Такие ситуации могут возникнуть, например, при компиляции из исходников, утечках. Так же swap используется при гибернации, когда содержимое оперативной памяти сохраняется на диск и при следующем запуске вы сможете полностью восстановить состояние.

В дальнейших примерах предполагается, что у нас установлена Windows, которая занимает 4 раздела: recovery, efi, reserved, Windows. Поэтому в примерах новый раздел nvme0n1p5.

Создание файловой системы и монтирование

Вариант №1: Btrfs

# Сначала монтируем раздел
mount /dev/nvme0n1p5 /mnt

# Потом создаем на нем подтома
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@swap

# Теперь мы демонтируем устройство
umount /mnt

mkdir -p /mnt/boot/efi /mnt/var/swap /mnt/home

# Монтируемся

# ZStandard ‒ это самый оптимальный метод сжатия. Если компьютер слабый, то лучше использовать lzo.
mount -o rw,noatime,compress=zstd:3,ssd,space_cache,subvol=@ /dev/nvme0n1p5 /mnt
mount /dev/nvme0n1p2 /mnt/boot/efi
mount -o noatime,compress=zstd:3,space_cache,subvol=@home /dev/nvme0n1p5 /mnt/home
mount -o rw,noatime,compress=no,ssd,space_cache,subvol=@swap /dev/nvme0n1p5 /mnt/var/swap
# Создаем файл подкачки
touch /mnt/var/swap/swapfile
# chattr +C должна быть применена к пустому файлу!
# Тут я перестраховываюсь, так как для подтома сжатие отключено
chattr +C /mnt/var/swap/swapfile
# С 16GB оперативной памяти нужно иметь файл подкачки минимум 4GB, 8 ‒ еще лучше (для гибернации нужно не менее 1/3 размера от RAM), а 32GB ‒ идеально
fallocate -l 4G /mnt/var/swap/swapfile
chmod 600 /mnt/var/swap/swapfile
mkswap /mnt/var/swap/swapfile
swapon /mnt/vra/swap/swapfile
### Вариант №2: LVM
# Создадим группу на разделе без файловой системы
vgcreate linux /dev/nvme0n1p5
# Теперь создадим в ней логические разделы:
lvcreate -L 30G linux -n root
lvcreate -L 20G linux -n home
# Можно для раздела отдать все оставшееся место
lvcreate -L +100%FREE linux -n home
mkfs.ext4 /dev/linux/root
mkfs.ext4 /dev/linux/home
mount /dev/linux/root /mnt
mkdir /mnt/home
mount /dev/linux/home /mnt/home
# Создаем файл подкачки. Не нужно верить дурачкам: он нужен всегда. Без него система будет лагать
fallocate -l 2G /mnt/swapfile
# Если хотим использовать гибернацию, то размер файла подкачки должен составлять около 2/5 от размера оперативной памяти на современном компьютере, в идеале он должен быть ему равен либо даже больше
# fallocate -l `awk '/Mem:/ {print $2}' <(free -m)`M /mnt/swapfile
chmod 600 /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p2 /mnt/boot/efi

Установка пакетов

pacstrap /mnt base base-devel linux linux-firmware linux-headers btrfs-progs efibootmgr ntfs-3g exfat-utils os-prober grub iw dialog wpa_supplicant nano vim wget zsh gnome gnome-extra

base-devel содержит набор утилит для компиляции, позже пригодится

Генерируем fstab

genfstab -U /mnt >> /mnt/etc/fstab

arch-chroot

arch-chroot /mnt

При использовании LVM нужно выполнить чуть больше действий:

# Предотвращаем ошибки lvm:
#   WARNING: Failed to connect lvmetad...
#   WARNING: Device /dev/nvme0n1 not initialized in udev database...
mkdir /mnt/hostlvm
mount --bind /run/lvm /mnt/hostlvm
arch-chroot /mnt
ln -s /run/lvm /hostlvm

Настраиваем дату и локаль

ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime
hwclock --systohc

Далее:

nano /etc/locale.gen

Раскоментируем:

en_US.UTF-8 UTF-8
...
ru_RU.UTF-8 UTF-8

Генерируем локали:

locale-gen

Задаем язык системы:

localectl set-locale LANG=en_US.UTF-8

Так же нужно настроить Linux Console (в нее мы можем попасть, нажав случайно Ctrl+Alt+F):

# Список всех доступных русских раскладок клавиатуры
ls /usr/share/kbd/keymaps/i386/qwerty/ru*

# Русская раскладка с переключением по Alt+Shift
echo 'KEYMAP="ruwin_alt_sh-UTF-8"' > /etc/vconsole.conf

# аналогично вызову
localectl set-keymap ruwin_alt_sh-UTF-8

# Шрифт с поддержкой кирилицы
echo 'FONT="cyr-sun16"' >> /etc/vconsole.conf

Настройка раскладки клавиатуры в X.Org:

localectl --no-convert set-x11-keymap us,ru pc105 "" grp:alt_shift_toggle

pc105 отличается от pc104 наличием клавиш: «|», «<», «>».

Прописываем хосты

echo "sergey-pc" > /etc/hostname
nano /etc/hosts

Добавляем в файл такие строки:

127.0.0.1 localhost
::1 localhost
127.0.1.1 sergey-pc.localdomain sergey-pc

Initramfs

mkinitcpio это Bash скрипт используемый для создания начального загрузочного диска системы. Из mkinitcpio man page:

⚠ Это обязательный шаг даже, если не используется LVM, а так же при изменение пути до корня

При использовании LVM нужно отредактировать /etc/mkinitcpio.conf и модифицировать список HOOKS, добавив lvm2 ДО ЗНАЧЕНИЯ filesystems:

HOOKS=(base udev autodetect modconf block lvm2 filesystems keyboard fsck)

Генерация:

mkinitcpio -p linux

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

# Создаем нового пользователя
useradd -m -g users -G wheel -s /bin/zsh sergey

# Устанавливаем для него пароль
passwd sergey

# Лочим пользователя root, чтобы из под него нельзя было авторизоваться
passwd -l root

Теперь в файле /etc/sudoers нужно раскоментировать строку:

%wheel ALL=(ALL:ALL) ALL

Установка grub

grub-install --target=x86_64-efi --efi-directory=/boot/efi

Чтобы отключить автоматическую загрузку Linux, редактируем дефолтный конфиг груба:

nano /etc/default/grub

Меняем GRUB_TIMEOUT, если не хотите чтобы Arch грузился автоматически через 5 секунд ожидания на экране Grub:

GRUB_TIMEOUT=-1

Затем генерируем grub:

grub-mkconfig -o /boot/grub/grub.cfg

Завершение

systemctl enable gdm
systemctl enable NetworkManager
exit
reboot

Дополнительно

Swappines

$ cat /proc/sys/vm/swappiness
60

При 60% свободной памяти, система начнет активно использовать своп.

Изменяем это поведение:

$ sudo sysctl -w vm.swappiness=1

Чтобы сделать значение постоянным, создаем /etc/sysctl.d/99-swappiness.conf со следующим содержимым:

vm.swappiness=1
$ sudo sysctl --system

man & help

$ man [ <section> ] <page>

# Section	Description
# 1	General Commands
# 2	System Calls
# 3	Library functions, covering in particular the C standard library
# 4	Special files (usually devices, those found in /dev) and drivers
# 5	File formats and conventions
# 6	Games and screensavers
# 7	Miscellanea
# 8	System administration commands and daemons

# Узнать где хранятся страницы манулов можно так
$ manpath
/usr/local/man:/usr/local/share/man:/usr/share/man

$ man -w printf
/usr/share/man/man1/printf.1.gz

# Поиск страниц по ключевому слову
$ man -k printf

# Смотрим все страницы
$ man -f printf
printf (1)           - format and print data
printf (1p)          - write formatted output
printf (3)           - formatted output conversion
printf (3p)          - print formatted output

# Выбираем конкретную
$ man 1p printf

# Краткая справка по функции
$ command -h
$ command --help

Типы файлов в выводе ls и других стандартных команд

There is only 1 command you need to know, which will help you to identify and categorize all the seven different file types found on the Linux system.

$ ls -ld <file name>

Here is an example output of the above command.

 $ ls -ld /etc/services
-rw-r--r-- 1 root root 19281 Feb 14  2012 /etc/services

ls command will show the file type as an encoded symbol found as the first character of the file permission part. In this case it is "-", which means "regular file". It is important to point out that Linux file types are not to be mistaken with file extensions. Let us have a look at a short summary of all the seven different types of Linux file types and ls command identifiers:

- : regular file
d : directory
c : character device file
b : block device file
s : local socket file
p : named pipe
l : symbolic link

Пакетные менеджеры

Пакетным менеджером по-умолчанию для Arch Linux является pacman. Для подсветки вывода pacman в /etc/pacman.conf нужно раскомментировать Color. Пользовательским репозиторием является AUR. Пакеты из него можно использовать только на свой страх и риск, но использовать все же придется ведь в официальных репозиториях много нету. Чтобы не собирать пакеты вручную можно поставить yay:

sudo pacman -S git
cd /tmp
git clone https://aur.archlinux.org/yay-bin.git
cd yay-bin
makepkg -si

Пакеты всегда нужно ставить из репозиториев. Смысла собирать их из исходников нет, так как в AUR и так самые последние версии. Так будет меньше хлама оставаться в системе после их удаления.

Синтаксис команды Yay аналогичен pacman. Так что будет полезным почитать справку по pacman.

Ссылки:

Нужные пакеты

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

yay -Sy linux-headers \ # нужны для компиляции некоторых программ
  wget \ # позволяет выполнять HTTP-запросы, скачивать файлы
  curl \ # делает то же самое, что и предыдущий
  adobe-source-code-pro-fonts \ # шрифт для терминала, нужен для темы Oh My Zsh! agnoster
  ttf-droid \ # шрифт по-умолчанию для VScode
  \ # шрифты по-умолчанию для Chrome
  \ # consolas-font \
  \ # ttf-ms-fonts \
  arc-gtk-theme-git \ # тема для интерфейса
  apache \ # самый популярный веб-сервер
  apache-tools \ # содержит ab, нагрузочный клиент
  \ # blender \ # самый простой 3D-редактор
  dconf-editor \ # все настройки gnome в одном месте
  dmraid \ # утилита для работы с raid-массивами дисков
  docker-compose \ # содержит docker и docker compose
  exfat-utils \ # добавляет поддержку файловой системы exfat
  firefox \ # один из лучших браузеров, единственный конкурент Chrome и единственный популярный non-chromium браузер
  flat-remix-git \ # тема с иконками
  \ # gimp \ # скромненький аналог Photoshop
  gnome-panel \ # я ставил только чтобы ярлыки из GUI создавать
  google-chrome \ # лучший браузер, противники проприетарщины предпочитают chromium
  chrome-gnome-shell \ # позволяет устанавливать расширения для Gnome
  gparted \ # графическая оболочка для разметки дисков
  htop \ # показывает запущенные процессы, загрузку cpu и потребление памяти
  \ # inkscape \ # векторный графический редактор
  \ # mariadb \ # свободная реализация самой популярной СУБД MySQL
  mc \ # аналог виндового Far + mcedit, замена nano
  \ # mongodb-bin \ # лучшая NoSQL база данных
  net-tools \ # содержит netstat
  neofetch \ # выводит в консоль информацию о системе
  nginx \ # самый быстрый веб-сервер
  ntfs-3g \ # добавляет поддержку файловой системы ntfs
  \ # nvm \ # менеджер версий для Node.js
  \ # postgresql \ # лучшая SQL база данных
  \ # phpenv \ # менеджер версий для PHP
  \ # pyenv \ # менеджер версий для Python
  asdf-vm \ # Заменяет собой все выше перечисленные менеджеры версий
  \ # pgadmin4 \ # админка для Postgres
  \ # pgmodeler \ # визуальный редактор для моделирования в Postgres
  \ # redis \ # СУБД в оперативной памяти, используемая для межпроцессового взаимодействия
  smartmontools \ # утилита для проверки состояния SSD
  telegram-desktop-bin \ # лучший мессенджер
  texmaker \ # редактор LaTex, генерирует PDF
  tor \ # сервис, который можно использовать для подключения к сети Tor
  torsocks \ # утилита torify, которая заставляет другие программы работать через Tor
  transmission-qt \ # торрент-клиент
  thunderbird \ # email-клиент
  virtualbox \ # виртуальная машина, позволяет запускать Windows и Linux
  visual-studio-code-bin \ # лучший бесплатный текстовый редактор
  vlc \ # видеоплеер
  websocat-bin \ # утилита для тестированя вебсокетов
  woeusb \ # создание загрузочных флешек с Windows
  xclip \ # копирование файла в буффер обмена из консоли
  seahorse \ # Приложение для управления паролями, а так же PGP и SSH ключами
  baobab \ # Приложения для мониторинга дисков
  jq \ # Утилита для работы с JSON
  pv \ # получает на вход поток и перенаправляет его, показывая статистику
  httpie \ # лучшая замена curl с подсветкой вывода
  tor-browser \ # Tor браузер
  

Заменяем ядро на стабильное

Если надоело, что что-то ломается почти после каждого обновления ядра, запускаем терминал и выполняем:

yay -S linux-lts linux-headers-lts
yay -R linux linux-headers
mkinitcpio -p linux

Масштабировавние 150% как в Windows

По-умолчанию в Gnome масштабирование кратно 100. Чтобы добавить варианты масштабирования 125% и 150% нужно выполнить в терминале:

gsettings set org.gnome.mutter experimental-features "['scale-monitor-framebuffer']"

Отключение:

gsettings reset org.gnome.mutter experimental-features

Расширения для Gnome

Устанавливаем расширение для Chrome.

image

Управление расширениями осуществляется через Tweaks.

image

Расширения для установки:

Название Описание
Dash to Dock. Выезжающий Dash - панель с избранными приложениями
Desktop Icons Иконки на рабочем столе
ShellTile Тайловый менеджер
Log Out Button Добавляет кнопку, которая выполняет выход из системы

Пользовательские сочетания клавиш

В Settings → Devices → Keyboard добавляем сочетания клавиш:

  • Ctrl + Alt + T для запуска терминала (gnome-terminal);
  • Ctrl + Alt + V для запуска Visual Code (code).

image

Запуск исполняемых файлов по двойному клику в Nautilus

Заставляем Nautilus выполнять исполняемые файлы вместо открытия их в текстовом редакторе. Нужно нажать на три точки, а потом выбрать Preferences:

image

Добавляем новые действия в контекстное Nautilus

$ yay -S filemanager-actions

У программы есть интерфейс, который позволяет добавлять свои команды. Существуют два плейсхолдера: %d для текущего каталога и %f для файла.

To install nautilus-action on Ubuntu, run simply this command via the Terminal:

sudo apt-get install nautilus-actions
(or equivalant packet manager as yum or pacman)

After the installation is complete, let's now see a quick example of how to add an extra action to the right-click menu with nautilus-actions.

The example consists of adding to the right-click menu the "Edit With Gimp" action to edit, for example, image files using The Gimp (Image Editor).

_Using the dash search "nautilus-actions" and click Nautilus-Actions Configuration.

_Under the Action tab, fill the following fields:

Context label: The text that will be displayed in the right-click menu, in our example, it's "Edit With Gimp"
Icon: This option allows to select an icon for your action (optional)
_Open now the Command tab and fill in the following fields:

Label: Enter any label of your choice for your action.
Path: Enter the path to the program you want to use using the Browse button. For our example, we will simply type "gimp".
Parameters: Click the Legend button to get suggested parameters. In our example, we will use the %f parameter to be able to edit image files with The Gimp.
_Log out the current session and log on again, or simply restart Nautilus with these commands from the Terminal:

nautilus -q
nautilus

Страница проекта.

Шаблоны файлов

Чтобы в Nautilus в контекстном меню отображался пункт New Document, нужно в ~/Templaytes создать шаблоны файлов:

touch ~/Templates/{Empty\ Document,Text\ Document.txt,README.md,pyfile.py}

Гибернация

Режим гибернациии от режима сна отличается тем, что в первом случае содержимое оперативной памяти сохраняется на жесткий диск и питание полностью отключается, во втором - питание подается только на оперативку. Чем хороша гибернация? - Например, мы работаем в Linux, вошли в режим гибернации, а затем загрузились в Windows и играем. Когда мы в следующий раз загрузимся в Linux, то увидим все то, что было перед выключением. Прекрасно?! Но часто ли такое нужно?

При переходе в режим гибернации делается дамп используемой оперативной памяти на диск. Размер файла/раздела подкачки для этих целей советуют делать не менее 2/5 от объема RAM на современных компьютерах. Так же можно применять сжатие при дампе. Про гибернацию лучше почитать здесь.

Режим гибернации по-умолчанию отключен. Чтобы его включить для начала нужно узнать UUID раздела, где расположен своп:

$ lsblk `df /swapfile | awk '/^\/dev/ {print $1}'` -no UUID
217df373-d154-4f2e-9497-fcac21709729

А затем сектор диска с которого начинается файл:

$ sudo filefrag -v /swapfile | awk 'NR == 4 {print $5}' | cut -d ':' -f 1
1423360

Если swapfile размещен на Btrfs, то описанный выше способ работать не будет.

# Для начала нужно скачать специальную утилиту для определения физического расположения файла
$ cd /tmp
$ wget https://raw.githubusercontent.com/osandov/osandov-linux/master/scripts/btrfs_map_physical.c
$ gcc -O2 -o btrfs_map_physical btrfs_map_physical.c  
# переместим исполняемый файл
$ sudo mv btrfs_map_physical /usr/local/bin
$ sudo chmod +x /usr/local/bin/btrfs_map_physical

# Использование
$ sudo btrfs_map_physical /swap/swapfile
FILE OFFSET	FILE SIZE	EXTENT OFFSET	EXTENT TYPE	LOGICAL SIZE	LOGICAL OFFSET	PHYSICAL SIZE	DEVID	PHYSICAL OFFSET
0	4096	0	regular	268435456	91029504	268435456	191029504
...

# Нас интересует последняя цифра. Ее нужно поделить на 4096 (размер блока) и результат указать в resume_offset
$ echo $((`sudo btrfs_map_physical /swap/swapfile | head -n 2 | tail -n 1 | cut -f9` / 4096))
22224

screenshot from 2019-02-23 02-12-34

В /etc/default/grub прописать:

GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=UUID=217df373-d154-4f2e-9497-fcac21709729 resume_offset=1423360"

resume_offset нужен только для файла. Для дисков и разделов вместо UUID можно указывать /dev/sda3 или /dev/mapper/linux-swap.

Теперь нужно изменить /etc/mkinitcpio.conf:

# resume должен следовать после filesystems
HOOKS=(...filesystems resume...)

Обновляем grub и генерируем initramfs:

sudo grub-mkconfig -o /boot/grub/grub.cfg
sudo mkinitcpio -p linux

Сам переход в режим гибернации выглядит так:

systemctl hibernate

Чтобы появилась кнопка для перехода в режим гибернации ставим расширение.

image
image

RAID

Аппаратный RAID

В Linux RAID на аппаратном уровне называют FakeRAID. Для работы с FakeRAID используется пакет dmraid.

Редактируем конфиг mkinitcpio:

sudo nano /etc/mkinitcpio.conf

В хуки добавляем dmraid:

HOOKS=(base udev autodetect modconf block lvm2 dmraid filesystems keyboard fsck)

И генерируем mkinitcpio:

sudo mkinitcpio -p linux

На моей материнке с чипсетом b450 с апаратным RAID из Linux работать нельзя: нет драйвера.

Программный Windows RAID

Этот раздел можно было бы озаглавит как RAID, доступный в Windows и в Linux. В Windows, в Disk Management нужно создать Striped Volume, аналог RAID 0 (правой кнопкой мыши по нужному диску). Это когда данные пишутся параллельно на разные устройства без дублирования. Одтн блок пишется на один диск, другой на второй, причем одновременно. Чтение происходит также. Таким образом при использовании 2 дисков мы получаем двойную скорость чтения/записи.

$ yay -S ldmtool

$ sudo ldmtool scan                                                
[
  "8d0cc1a7-b10c-11e9-80d3-b42e9916909d"
]

$ sudo ldmtool show diskgroup 8d0cc1a7-b10c-11e9-80d3-b42e9916909d 
{
  "name" : "DESKTOP-VR9KKHM-Dg0",
  "guid" : "8d0cc1a7-b10c-11e9-80d3-b42e9916909d",
  "volumes" : [
    "Volume1"
  ],
  "disks" : [
    "Disk1",
    "Disk2"
  ]
}

$ sudo ldmtool create all                                          
[
  "ldm_vol_DESKTOP-VR9KKHM-Dg0_Volume1"
]

Теперь можно монтировать устройство /dev/mapper/ldm_vol_DESKTOP-VR9KKHM-Dg0_Volume1.

Но нам нужно чтобы устройство автоматически создавалось. Для этого нужно создать сервис /etc/systemd/system/ldmtool.service:

[Unit]
Description=Windows Dynamic Disk Mount
Before=local-fs-pre.target
DefaultDependencies=no
[Service]
Type=simple
User=root
ExecStart=/usr/bin/ldmtool create all
[Install]
WantedBy=local-fs-pre.target

Включим его:

$ sudo systemctl enable ldmtool.service

Редактируем /etc/fstab:

/dev/mapper/ldm_vol_DESKTOP-VR9KKHM-Dg0_Volume1 /mnt/d ntfs-3g rw,user,fmask=0111,dmask=0000 0 0

В Windows есть так же технология Storage Spaces, но ее поддержка в Linux не реализована.

Права

4 - Чтение (r)
2 - Запись (w)
1 - Выполнение (x)

Сумма этих чисел дает разные сочетания типа:
1 + 2 + 4 = 7 или 1 + 4 = 5

Права задаются тремя числами, например, 755, где первое число – права владельца, далее: группа и остальные пользователи. Владелец может делать все (1 + 2 + 4 = 7), другие пользователи – только читать и исполнять файлы (1 + 4 = 5).

Для работы с правами на файлы используется команда chroot:

chroot --help

В Python права можно записывать так:

0o755
$ ll
total 20K
drwxr-xr-x 3 sergey sergey 4,0K июн 20 17:22 backend
...

d         | rwx      | r-x    | r-x
тип файла | владелец | группа | остальные

Ссылки:

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

$ sudo mount [ -t <fs> ] <device> <path> [ -o <options> ]

# Можно монтировать образы, созданные через dd
mount -t fstype -o loop,ro image.dd /mntpoint

Опции:

ro     Mount the filesystem read-only.

rw     Mount the filesystem read-write.

sync   All I/O to the filesystem should be done synchronously.  In  the
	case  of  media with a limited number of write cycles (e.g. some
	flash drives), sync may cause life-cycle shortening.

user   Allow an ordinary user to mount the filesystem.  The name of the
	mounting  user  is  written  to the mtab file (or to the private
	libmount file in /run/mount on systems without a  regular  mtab)
	so  that  this same user can unmount the filesystem again.  This
	option implies the options noexec,  nosuid,  and  nodev  (unless
	overridden   by  subsequent  options,  as  in  the  option  line
	user,exec,dev,suid).

noexec ‒ запретить выполнение файлов
noatime ‒ не обновлять время домступа к файлу
defaults = rw,suid,dev,exec,auto,nouser,async
uid ‒ 1000 для первого пользователя
gid ‒ см. далее

$ id
uid=1000(sergey) gid=985(users) groups=985(users),969(docker),998(wheel)

users  Allow any user to mount and to unmount the filesystem, even when
	some other ordinary user mounted it.  This  option  implies  the
	options  noexec,  nosuid, and nodev (unless overridden by subse‐
	quent options, as in the option line users,exec,dev,suid).

umask=value
	Set the umask (the bitmask  of  the  permissions  that  are  not
	present).  The default is the umask of the current process.  The
	value is given in octal.

dmask=value
	Set the umask applied to directories only.  The default  is  the
	umask of the current process.  The value is given in octal.

fmask=value
	Set the umask applied to regular files only.  The default is the
	umask of the current process.  The value is given in octal.

Указываются права не в виде восьмиричного числа!

    0   1   2   3   4   5   6   7
r   +   +   +   +   -   -   -   -
w   +   +   -   -   +   +   -   -
x   +   -   +   -   +   -   +   -

Например, 0755 = 0022

Добавляем путь в PATH

  • Bash Shell: ~.bash_profile, ~/.bashrc or ~/.profile
  • Korn Shell: ~/.kshrc or ~/.profile
  • Z Shell: ~/.zshrc or ~/.zshenv
export PATH=/path/to/bin:$PATH

Системные переменные окружения

Edit /etc/environment format: KEY=VALUE.

bin в домашнем каталоге

mkdir ~/.local/bin

cat << __EOF__ >> ~/.zshenv
typeset -U path
path=(~/.local/bin ~/bin $path[@])
__EOF__

Теперь самописные скрипты можно кидать в ~/.local/bin, так они будут доступны только для текущего пользователя.

~/.local/bin/hello:

#!/usr/bin/env bash

echo "Hello World!"

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

$ chmod +x ~/.local/bin/hello

Проверка:

$ source ~/.zshenv
$ hello
Hello World!

Монтируем Windows разделы

$ sudo mkdir /mnt/c

Редактируем /etc/fstab:

/dev/nvme0n1p4 /mnt/c ntfs-3g rw,user,fmask=0111,dmask=0000 0 0

Шрифты

Шрифты надо кидать в /usr/share/fonts либо в ~/.fonts или в ~/.local/share/fonts.

# Обновить шрифты
$ fc-cache -f -v

# Чтобы проверить установлен ли шрифт
$ fc-list | grep "<name-of-font>"

Шарим Windows шрифты:

$ sudo ln -sf /mnt/c/Windows/Fonts /usr/share/fonts/WindowsFonts

screenshot from 2019-02-20 23-17-46

Наборы шрифтов:

Emoji

# Вариант 1
yay -S ttf-joypixels
# Добавим конфиг с фолбэками (убедитесь, что он там есть)
sudo ln -s /etc/fonts/conf.avail/75-joypixels.conf  /etc/fonts/conf.d
# Обновим кэш шрифтов
fc-cache -f

# Вариант 2
yay -S noto-fonts-emoji
# mkdir -p ~/.config/fontconfig
# можно локально задать в ~/.config/fontconfig/fonts.conf
sudo tee /etc/fonts/conf.avail/75-noto-color-emoji.conf << __EOF__ > /dev/null
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>

    <!-- Add generic family. -->
    <match target="pattern">
        <test qual="any" name="family"><string>emoji</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <!-- This adds Noto Color Emoji as a final fallback font for the default font families. -->
    <match target="pattern">
        <test name="family"><string>sans</string></test>
        <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test name="family"><string>serif</string></test>
        <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test name="family"><string>sans-serif</string></test>
        <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test name="family"><string>monospace</string></test>
        <edit name="family" mode="append"><string>Noto Color Emoji</string></edit>
    </match>

    <!-- Block Symbola from the list of fallback fonts. -->
    <selectfont>
        <rejectfont>
            <pattern>
                <patelt name="family">
                    <string>Symbola</string>
                </patelt>
            </pattern>
        </rejectfont>
    </selectfont>

    <!-- Use Noto Color Emoji when other popular fonts are being specifically requested. -->
    <match target="pattern">
        <test qual="any" name="family"><string>Apple Color Emoji</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Segoe UI Emoji</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Segoe UI Symbol</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Android Emoji</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Twitter Color Emoji</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Twemoji</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Twemoji Mozilla</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>TwemojiMozilla</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>EmojiTwo</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Emoji Two</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>EmojiSymbols</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

    <match target="pattern">
        <test qual="any" name="family"><string>Symbola</string></test>
        <edit name="family" mode="assign" binding="same"><string>Noto Color Emoji</string></edit>
    </match>

</fontconfig>
__EOF__
sudo ln -sf /etc/fonts/conf.avail/75-noto-color-emoji.conf /etc/fonts/conf.d/
fc-cache -f -v

Теперь глифы эмодзи, если они отсутствуют у шрифта будут браться из JoyPixels.

Спецсимволы

Для вставки специальных символов в Gnome применяется сочетание клавиш Ctrl+Shift+U, далее вводим 4-х значный код символа.

Символ Unicode
« 00ab
» 00bb
© 00a9
2122
§ 00a7
2013
20ac
20bd
2192
λ 03bb

Сетевые интерфесы

$ ifconfig -a
...
enp5s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.106  netmask 255.255.255.0  broadcast 192.168.0.255
...

# inet 192.168.0.106 ‒ это наш адрес в локальной сети, если запустить на локальной машине nginx, то перейдя по ссылке http://192.168.0.106 мы увидим приветствие Nginx

Расшифрорвка имен:

Two character prefixes based on the type of interface:
 *   en -- ethernet
 *   sl -- serial line IP (slip)
 *   wl -- wlan
 *   ww -- wwan

Так же можно менять свой локальный ip.

Ссылки:

(Linux ifconfig command)[https://www.computerhope.com/unix/uifconfi.htm].

Блокируем сайты с рекламой через hosts

# Сохраняем копию оригинального файла
$ cp /etc/hosts ~/Documents/hosts.bak
$ wget -qO- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | sudo tee --append /etc/hosts

Информация о железе

$ lspci
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09)
00:01.0 PCI bridge: Intel Corporation Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port (rev 09)
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09)
00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller (rev 04)
00:16.0 Communication controller: Intel Corporation 7 Series/C216 Chipset Family MEI Controller #1 (rev 04)
00:1a.0 USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced Host Controller #2 (rev 04)
00:1b.0 Audio device: Intel Corporation 7 Series/C216 Chipset Family High Definition Audio Controller (rev 04)
00:1c.0 PCI bridge: Intel Corporation 7 Series/C216 Chipset Family PCI Express Root Port 1 (rev c4)
00:1c.4 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 5 (rev c4)
00:1c.5 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 6 (rev c4)
00:1c.6 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 7 (rev c4)
00:1d.0 USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced Host Controller #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation H77 Express Chipset LPC Controller (rev 04)
00:1f.2 IDE interface: Intel Corporation 7 Series/C210 Series Chipset Family 4-port SATA Controller [IDE mode] (rev 04)
00:1f.3 SMBus: Intel Corporation 7 Series/C216 Chipset Family SMBus Controller (rev 04)
00:1f.5 IDE interface: Intel Corporation 7 Series/C210 Series Chipset Family 2-port SATA Controller [IDE mode] (rev 04)
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 09)
04:00.0 Network controller: Qualcomm Atheros AR9485 Wireless Network Adapter (rev 01)
05:00.0 IDE interface: Marvell Technology Group Ltd. 88SE9172 SATA III 6Gb/s RAID Controller (rev 11)

# Видеоадаптер(ы)
$ lspci -v | grep "VGA" -A 12

# SATA-устройства
$ lsscsi

# Список USB-устройств
$ lsusb

# Очень подробная информация о всех устройствах
$ inxi -Fx

$ hwinfo --short
cpu:
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3500 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3480 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3500 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3491 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3550 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3484 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3492 MHz
                       Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz, 3496 MHz
keyboard:
  /dev/input/event2    Logitech Keyboard K120
mouse:
  /dev/input/mice      Logitech M-U0004 810-001317 [B110 Optical USB Mouse]
monitor:
                       SAMSUNG SMS24A650
                       SAMSUNG SMB2340
graphics card:
                       Intel 2nd Generation Core Processor Family Integrated Graphics Controller
sound:
                       Intel 7 Series/C216 Chipset Family High Definition Audio Controller
storage:
                       Intel 7 Series/C210 Series Chipset Family 4-port SATA Controller [IDE mode]
                       Intel 7 Series/C210 Series Chipset Family 2-port SATA Controller [IDE mode]
                       Marvell 88SE9172 SATA III 6Gb/s RAID Controller
network:
  enp3s0               Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
  wlp4s0               Qualcomm Atheros AR9485 Wireless Network Adapter
network interface:
  docker0              Ethernet network interface
  enp3s0               Ethernet network interface
  lo                   Loopback network interface
  wlp4s0               Ethernet network interface
  br-1d7c88a3dc61      Ethernet network interface
disk:
  /dev/sdb             WDC WD5000AZLX-0
  /dev/sda             INTEL SSDSC2CW24
partition:
  /dev/sdb1            Partition
  /dev/sda1            Partition
  /dev/sda2            Partition
  /dev/sda3            Partition
usb controller:
                       Intel 7 Series/C216 Chipset Family USB Enhanced Host Controller #2
                       Intel 7 Series/C216 Chipset Family USB Enhanced Host Controller #1
                       Intel 7 Series/C210 Series Chipset Family USB xHCI Host Controller
bios:
                       BIOS
bridge:
                       Intel 7 Series/C216 Chipset Family PCI Express Root Port 1
                       Intel H77 Express Chipset LPC Controller
                       Intel Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
                       Intel 7 Series/C210 Series Chipset Family PCI Express Root Port 6
                       Intel 2nd Generation Core Processor Family DRAM Controller
                       Intel 7 Series/C210 Series Chipset Family PCI Express Root Port 7
                       Intel 7 Series/C210 Series Chipset Family PCI Express Root Port 5
hub:
                       Intel Integrated Rate Matching Hub
                       Linux Foundation 2.0 root hub
                       Linux Foundation 3.0 root hub
                       Linux Foundation 2.0 root hub
                       Intel Integrated Rate Matching Hub
                       Linux Foundation 2.0 root hub
memory:
                       Main Memory
unknown:
                       FPU
                       DMA controller
                       PIC
                       Keyboard controller
  /dev/lp0             Parallel controller
                       Intel 7 Series/C216 Chipset Family MEI Controller #1
                       Intel 7 Series/C216 Chipset Family SMBus Controller
                       Serial controller
  /dev/input/event3    Logitech Keyboard K120

# Список блочных устройств
$ lsblk

# Покажет разделы и занимаемое ими место
$ df -h

# Fdisk is a utility to modify partitions on hard drives, and can be used to list out the partition information as well.

$ sudo fdisk -l

Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x30093008

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *          63   146801969    73400953+   7  HPFS/NTFS/exFAT
/dev/sda2       146802031   976771071   414984520+   f  W95 Ext'd (LBA)
/dev/sda5       146802033   351614654   102406311    7  HPFS/NTFS/exFAT
/dev/sda6       351614718   556427339   102406311   83  Linux
/dev/sda7       556429312   560427007     1998848   82  Linux swap / Solaris
/dev/sda8       560429056   976771071   208171008   83  Linux

# The mount is used to mount/unmount and view mounted file systems.

$ mount | column -t
/dev/sda6    on  /                                            type  ext4             (rw,errors=remount-ro)
proc         on  /proc                                        type  proc             (rw,noexec,nosuid,nodev)
sysfs        on  /sys                                         type  sysfs            (rw,noexec,nosuid,nodev)
none         on  /sys/fs/cgroup                               type  tmpfs            (rw)
none         on  /sys/fs/fuse/connections                     type  fusectl          (rw)
none         on  /sys/kernel/debug                            type  debugfs          (rw)
none         on  /sys/kernel/security                         type  securityfs       (rw)
udev         on  /dev                                         type  devtmpfs         (rw,mode=0755)
devpts       on  /dev/pts                                     type  devpts           (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs        on  /run                                         type  tmpfs            (rw,noexec,nosuid,size=10%,mode=0755)
none         on  /run/lock                                    type  tmpfs            (rw,noexec,nosuid,nodev,size=5242880)
none         on  /run/shm                                     type  tmpfs            (rw,nosuid,nodev)
none         on  /run/user                                    type  tmpfs            (rw,noexec,nosuid,nodev,size=104857600,mode=0755)
none         on  /sys/fs/pstore                               type  pstore           (rw)
/dev/sda8    on  /media/13f35f59-f023-4d98-b06f-9dfaebefd6c1  type  ext4             (rw,nosuid,nodev,errors=remount-ro)
/dev/sda5    on  /media/4668484A68483B47                      type  fuseblk          (rw,nosuid,nodev,allow_other,blksize=4096)
binfmt_misc  on  /proc/sys/fs/binfmt_misc                     type  binfmt_misc      (rw,noexec,nosuid,nodev)
systemd      on  /sys/fs/cgroup/systemd                       type  cgroup           (rw,noexec,nosuid,nodev,none,name=systemd)
gvfsd-fuse   on  /run/user/1000/gvfs                          type  fuse.gvfsd-fuse  (rw,nosuid,nodev,user=enlightened)

# Again, use grep to filter out only those file systems that you want to see

$ mount | column -t | grep ext

# The dmidecode command is different from all other commands. It extracts hardware information by reading data from the SMBOIS data structures (also called DMI tables).

# display information about the processor/cpu
$ sudo dmidecode -t processor

# memory/ram information
$ sudo dmidecode -t memory

# bios details
$ sudo dmidecode -t bios

# cpu information
$ cat /proc/cpuinfo

# memory information
$ cat /proc/meminfo

$ cat /proc/version
Linux version 3.11.0-12-generic (buildd@allspice) (gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu7) ) #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC 2013

# SCSI/Sata devices

$ cat /proc/scsi/scsi
Attached devices:
Host: scsi3 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: ST3500418AS      Rev: CC38
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi4 Channel: 00 Id: 00 Lun: 00
  Vendor: SONY     Model: DVD RW DRU-190A  Rev: 1.63
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Partitions

$ cat /proc/partitions
major minor  #blocks  name

   8        0  488386584 sda
   8        1   73400953 sda1
   8        2          1 sda2
   8        5  102406311 sda5
   8        6  102406311 sda6
   8        7    1998848 sda7
   8        8  208171008 sda8
  11        0    1048575 sr0

# The hdparm command gets information about sata devices like hard disks.

$ sudo hdparm -i /dev/sda

/dev/sda:

 Model=ST3500418AS, FwRev=CC38, SerialNo=9VMJXV1N
 Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs RotSpdTol>.5% }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=4
 BuffType=unknown, BuffSize=16384kB, MaxMultSect=16, MultSect=16
 CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=976773168
 IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120}
 PIO modes:  pio0 pio1 pio2 pio3 pio4
 DMA modes:  mdma0 mdma1 mdma2
 UDMA modes: udma0 udma1 udma2 udma3 udma4 udma5 *udma6
 AdvancedPM=no WriteCache=enabled
 Drive conforms to: unknown:  ATA/ATAPI-4,5,6,7

 * signifies the current active mode

Редактирование DConf

DConf хранит профили терминала в ~/.config/dconf/user, в формате GVDB пруф.

image

# Делаем дамп
$ dconf dump / > /tmp/dconf
# Редактируем и загружаем
$ dconf load / < /tmp/dconf

ZSH

Установка ZSH

$ yay -S zsh

Меняем shell на /bin/zsh:

$ chsh -s $(which zsh)

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

## [Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh)

Установка:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

Пакет из репозитория ставится вне домашнего каталога, а потому требует root права при установке плагинов, что не удобно.

Так же для некоторых тем Oh My Zsh нужны шрифты наподобие Powerline:

yay -S powerline-fonts

Ставим must-have плагины:

git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:=~/.oh-my-zsh/custom}/plugins/zsh-completions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

Изменяем .zshrc:

ZSH_THEME="agnoster"
...
plugins=(
  command-not-found
  extract
  git
  zsh-autosuggestions
  zsh-completions
  zsh-syntax-highlighting
)

autoload -Uz compinit && compinit

source $ZSH/oh-my-zsh.sh

Для темы Agnoster настройках терминала выбираем шрифт Source Code Pro Regular, чтобы отображались стрелочки.

Oh My ZSH/Command Not Found

Чтобы этот плагин работал нужно выполняить ряд действий:

# Устанавливаем пакет
$ yay -S pkgfile

# Инициализируем базу данных, где будет храниться информация о доступных пакетах
$ sudo pkgfile --update

# Включаем сервис для автообновления базы
$ sudo systemctl start pkgfile-update.timer
$ sudo systemctl enable pkgfile-update.timer

# Результат
$ ruby
ruby may be found in the following packages:
  extra/ruby 2.6.5-1            /usr/bin/ruby
  community/gitlab 12.3.5-1     /usr/share/webapps/gitlab/vendor/bundle/ruby/2.5.0/gems/hamlit-2.8.8/bin/ruby
  community/logstash 7.4.0-1    /usr/share/logstash/bin/ruby
  community/ruby2.5 2.5.7-1     /opt/ruby2.5/bin/ruby

ZPlug

Упрощает управление плагинами, позволяя все их прописать в одном месте. Лучше zgen тем, недостающие плагины сами ставятся.

$ yay -S zplug

Пример ~/.zshrc:

#!/usr/bin/env zsh

# History
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
# Шарим историю между сессиями
setopt SHARE_HISTORY
# Не сохраняем команды с пробелами в начале
setopt HIST_IGNORE_SPACE

fpath+=~/.zfunc

# if [[ ! -d ~/.zplug ]];then
#   git clone https://github.com/b4b4r07/zplug ~/.zplug
# fi

source /usr/share/zsh/scripts/zplug/init.zsh

zplug "robbyrussell/oh-my-zsh", as:plugin, use:"lib/*.zsh"

# https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins-Overview
zplug  "plugins/archlinux",                 from:oh-my-zsh
zplug  "plugins/colored-man-pages",         from:oh-my-zsh
zplug  "plugins/colorize",                  from:oh-my-zsh
zplug  "plugins/compleat",                  from:oh-my-zsh
zplug  "plugins/command-not-found",         from:oh-my-zsh
zplug  "plugins/common-aliases",            from:oh-my-zsh
zplug  "plugins/copydir",                   from:oh-my-zsh
zplug  "plugins/copyfile",                  from:oh-my-zsh
zplug  "plugins/extract",                   from:oh-my-zsh
zplug  "plugins/git",                       from:oh-my-zsh
zplug  "plugins/history",                   from:oh-my-zsh
zplug  "plugins/history-substring-search",  from:oh-my-zsh
zplug  "plugins/man",                       from:oh-my-zsh
zplug  "plugins/sudo",                      from:oh-my-zsh
zplug  "plugins/themes",                    from:oh-my-zsh
zplug  "plugins/urltools",                  from:oh-my-zsh
zplug  "plugins/vscode",                    from:oh-my-zsh
zplug  "plugins/web-search",                from:oh-my-zsh

zplug "zsh-users/zsh-autosuggestions"
zplug "zsh-users/zsh-completions"
zplug "zsh-users/zsh-syntax-highlighting"

setopt prompt_subst # Make sure prompt is able to be generated properly.
zplug "caiogondim/bullet-train.zsh", use:bullet-train.zsh-theme, defer:3 # defer until other plugins like oh-my-zsh is loaded

# Install plugins if there are plugins that have not been installed
if ! zplug check --verbose; then
  printf "Install? [y/N]: "
  if read -q; then
    echo; zplug install
  fi
fi

# Флаг --verbose служит для вывода отладочной информации
zplug load # --verbose

ZGen

Устарел.

Позволяет избавиться от мусора в ~/.zshrc.

$ yay -S zgen-git

Пример файла ~/.zshrc:

# load zgen
source /usr/share/zsh/share/zgen.zsh

# if the init script doesn't exist
if ! zgen saved; then

  # specify plugins here
  zgen oh-my-zsh
  zgen oh-my-zsh
  zgen oh-my-zsh plugins/archlinux
  zgen oh-my-zsh plugins/command-not-found
  zgen oh-my-zsh plugins/docker
  zgen oh-my-zsh plugins/extract
  zgen oh-my-zsh plugins/git
  zgen oh-my-zsh plugins/git-flow-avh
  zgen oh-my-zsh plugins/history
  zgen oh-my-zsh plugins/httpie
  zgen oh-my-zsh plugins/node
  zgen oh-my-zsh plugins/npm
  zgen oh-my-zsh plugins/pass
  zgen oh-my-zsh plugins/pip
  zgen oh-my-zsh plugins/python
  zgen oh-my-zsh plugins/sudo
  zgen oh-my-zsh plugins/systemd
  zgen oh-my-zsh plugins/vscode
  zgen load zsh-users/zsh-autosuggestions
  zgen load zsh-users/zsh-completions
  zgen load zsh-users/zsh-syntax-highlighting
  zgen load caiogondim/bullet-train-oh-my-zsh-theme bullet-train

  # generate the init script from plugins above
  zgen save
fi

После изменения ~/.zshrc нужно перешрузить Shell:

$ exec "$SHELL"

Все необходимые плагины будут скачены.

Новые плагины можно добавлять из терминала:

$ zgen load <plugin>
$ zgen oh-my-zsh <plugin>

А можно прописать в секцию для установки, а потом выполнить:

$ zgen reset
$ exec "$SHELL"

Я не уверен, что последнее правильно.

См. справку:

$ zgen --help

Новый плагины

Темы Oh My Zsh!

Bullet Train for oh-my-zsh

$ wget -P $ZSH_CUSTOM/themes https://raw.githubusercontent.com/caiogondim/bullet-train-oh-my-zsh-theme/master/bullet-train.zsh-theme

Jovial

# Сначала сохраняем копию zhsrc, потому как jovial изменить оригинальеный файл
$ cp ~/.zshrc ~/.zshrc.bak
$ curl -sSL git.io/jovial | sudo bash -s $USER

У меня эта тема упорно устанавливается в /root/.oh-my-zsh.

Powerlevel10k

Это красивая тема для ZSH.

git clone https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM/themes/powerlevel10k

~/.zshrc:

ZSH_THEME=powerlevel10k/powerlevel10k

Изменим prompt:

cd && curl -fsSLO https://raw.githubusercontent.com/romkatv/dotfiles-public/master/.purepower
echo 'source ~/.purepower' >>! ~/.zshrc

image

Подробнее про ZSH

Разноцветный cat

Цветовые схемы для терминала

# Интерактивная установка
# Падает с ошибкой, если нет профиля по-умолчаниюю для терминала
# Для всех созданных профилей будет использовавться шрифт профиля по-умолчанию
bash -c  "$(wget -qO- https://git.io/vQgMr)"
# Удаление всех профилей
dconf reset -f /org/gnome/terminal/legacy/profiles:/

Ссылки:

Бекап системы

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

mkdir /mnt/{backup,root}
mount /path/to/backup /mnt/backup
mount /path/to/root /mnt/root

# Делаем бекап
cd /mnt/root
tar -cvpzf /mnt/backup/root.tar.gz .

# Извлекаем бекапа
tar -xzpvf /mnt/backup/root.tar.gz -C /mnt/root

Ссылки:

asdf-vm

Установка asdf через Git:

git clone https://github.com/asdf-vm/asdf.git ~/.asdf
cd ~/.asdf
git checkout "$(git describe --abbrev=0 --tags)"

echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.zshrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.zshrc

Установка asdf через AUR:

yay -S asdf-vm

В ~/.zshrc (после compinit) добавляем строки:

. /opt/asdf-vm/asdf.sh
. /opt/asdf-vm/completions/asdf.bash

Устанавливаем переменную ASDF_DIR (нужна для плагина asdf oh-my-zsh) и добавляем в PATH путь до исполняемого файлаЖ.

sudo tee /etc/profile.d/asdf.sh << EOF > /dev/null
export ASDF_DIR="/opt/asdf-vm"
export PATH="$ASDF_DIR/bin:$PATH"
EOF

Удаление:

yay -Rns asdf-vm
rm -rf ~/.asdf/ ~/.tool-versions

Примеры:

$ asdf plugin-add python
$ asdf install python 3.7.3
$ asdf install python 2.7.15
$ asdf list python
  2.7.15
  3.7.3
$ asdf uninstall python 2.7.15
$ asdf global python 3.7.3
# Сделать системную версию Python глобальной
$ asdf global python system
$ which python
/home/sergey/.asdf/shims/python

$ asdf plugin-add nodejs
# see: <https://github.com/asdf-vm/asdf-nodejs#install>
$ bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring
$ asdf install nodejs 10.16.0
$ asdf global nodejs 10.16.0
$ which node
/home/sergey/.asdf/shims/node
$ which npm
/home/sergey/.asdf/shims/npm
$ asdf list
golang
  1.12
nodejs
  10.16.0
postgres
  11.4
python
  2.7.15
  3.7.3
sqlite
  3.29.0

Все доступные плагины. При установке, использовании плагинов могут возникать проблемы. Например, плагин для Python работает поверх pyenv и при возникновении проблем, следует изучить страницу «Common build problems».

If you use pip to install a module like ipython that has a binaries. You will need to run asdf reshim python for the binary to be in your path.

После установки через pip пакетов, которые добавляют команды, чтобы те были доступны, нужно всегда выполнять asdf reshim python.

Ссылки:

NVM

⚠️ Использование asdf-vm предпочительнее.

Устанавливаем последнюю версию Node.js:

nvm install node

Настройка Docker

$ yay -S docker
$ sudo systemctl start docker
$ sudo systemctl enable docker
# sudo groupadd docker
# groupadd: group 'docker' already exists
sudo usermod -aG docker $USER

Нужно выйти и войти в систему, а потом проверить:

$ docker run hello-world

Ссылка.

Настройка Visual Code

{
  "editor.fontSize": 16,
  "editor.rulers": [
    72,
    80,
    100,
    120
  ],
  "editor.tabSize": 2,
  "editor.wordWrap": "bounded",
  "editor.wordWrapColumn": 120,
  "files.insertFinalNewline": true,
  "files.trimFinalNewlines": true,
  "files.trimTrailingWhitespace": true,
  "terminal.integrated.fontFamily": "Source Code Pro"
}

LVM

Список логических разделов LVM:

$ sudo lvscan
  ACTIVE            '/dev/linux/root' [40.00 GiB] inherit
  ACTIVE            '/dev/linux/home' [20.00 GiB] inherit

Изменение размера логического раздела:

# Ключ -r выполняет resizefs
$ lvresize -r -L +10G /dev/linux/home

# Аналогично двум командам:

# Увеличиваем размер логического раздела
$ sudo lvresize -L +10GB /dev/mapper/linux-home

# После lvresize нужно обязательно изменить размер файловой системы
$ sudo resize2fs /dev/mapper/linux-home

# Делает то же самое, что и две команды выше
$ sudo lvresize -r -L +10GB /dev/mapper/linux-root

Переименование логического раздела:

$ sudo lvrename <oldname> <newname>

После нужно отредактировать /etc/fstab, изменив пути до разделов, а затем выполнить:

$ sudo grub-mkconfig -o /boot/grub/grub.cfg

Btrfs

Про снапшоты. В Btrfs есть механизм, аналогичный git, который позволяет фиксировать изменения снимками. Снапшоты хранят в себе только изменения между снимками, поэтому занимают мало места и по этой же причине не могут быть созданы вне текущей файловой системы. Они содержат только диффы. Как только мы создали снапшот, состояние системы зафиксировалось. Например у нас есть три файла: foo, bar, baz. Мы сделали снапшот, а потом удалили foo и baz, но пока существует снапшот эти файлы продолжат занимать место + если мы изменим bar, то и его первоначальная копия продолжит свое существование. Так что чтобы освободить место придется периодически удалять ненужные снапшоты.

Обнаружил баг: из-за своп-файла не делались снапшоты корня.

# Создать subvolume
$ sudo btrfs sub create /path/to/@name

# Создание снапшота
# Снапшоты являются разновидностью полдазделов, потому с ними можно выполнять те же операции
$ sudo mkdir /.snapshots
$ sudo chmod 750 /.snapshots

# Этой командой не получится создать снапшот на другой Btrfs (на флешке)
$ sudo btrfs sub snap -r /home /.snapshots/@home_`date +%F-%s`
Create a readonly snapshot of '/home' in '/.snapshots/@home_2019-07-15-1563181292'

$ sudo btrfs sub li -a /
ID 257 gen 1457 top level 5 path <FS_TREE>/@
ID 258 gen 1458 top level 5 path <FS_TREE>/@home
ID 281 gen 1458 top level 5 path <FS_TREE>/@var
ID 283 gen 1458 top level 257 path <FS_TREE>/@/.snapshots/@home_2019-07-15-1563181292

# Удаление снапшота аналогично удалению подраздела
$ sudo btrfs sub del /.snapshots/@home_2019-07-15-1563181292
Delete subvolume (no-commit): '/.snapshots/@home_2019-07-15-1563181292'

# Смонтировать subvolume/снапшот по указанному пути
$ sudo btrfs sub set-default <ID> /

# Восстановление данных

# С сохранением снапшота
$ cp -aR --reflink /.snapshots/@home_YYYY-MM-DD-ssssssssss /@home

# С удалением снапшота
# Таким же способом можно переименовывать подразделы/снапшоты
$ mv /.snapshots/@home_YYYY-MM-DD-ssssssssss /@home

$ btrfs filesystem df /
Data, single: total=15.01GiB, used=12.42GiB
System, single: total=4.00MiB, used=16.00KiB
Metadata, single: total=1.01GiB, used=772.20MiB
GlobalReserve, single: total=44.47MiB, used=0.00B

# Как сделать бекап и восстановить его в другой ФС
$ btrfs send /source/subvolume >/another/filesystem/subvolume-image   # just a file
# (or you can gzip it and/or send with nc on the fly, whatever)
# then later
$ </another/filesystem/subvolume-image btrfs receive /some/btrfs/directory

# Можно так же добавлять новые разделы и устройства в уже существующую ФС
# Можно так же сделатиь ограничения на размер подраздела, добавив его в группу и включив для него квоту
$ man btrfs
бтрфс ничего не жмет.
наилучший вариант сделать ридонли снапшот системы, потом из снапшота сделать образ через send и уж его можно жать и в хвост и в гриву
к примеру

sudo btrfs filesystem sync /
sudo btrfs subvolume snapshot -r / /mnt/backup/root_base
sudo btrfs send /mnt/b11/root_base | gzip > root_`date '+%F'`.gz

но почему бы не воспользоваться обыденным tar ??
так-то формат упаковки btrfs-stream (формат выхода btrfs send) не фундаментально отличается от формата tar. выполнить на сервере

sudo tar -czpf %backup%/srv4full-`date "+%F"`.tgz -X /etc/backupfull_exclude /

в файл /etc/backupfull_exclude пишешь список того что не нужно упаковывать в архив с системой (кроме классических /dev /proc /run /sys и прочих еще докинуть саму директорию куда архивишься  и плюс рабочие директории сервисов, к примеру база данных такую архивацию не всегда переживет)
а далее восстановление из tar архива

если свободного места на сервере будет меньше трети всего объема то такой бекап может не прокатить, либо жать сильнее к примеру через lzma (жрет памяти и проц очень хорошо) либо писать напрямую по интернету к себе (если будет разрыв то передача обломится)

Типы файловых систем:

Flat:

toplevel         (volume root directory, not to be mounted by default)
  +-- root       (subvolume root directory, to be mounted at /)
  +-- home       (subvolume root directory, to be mounted at /home)
  +-- var        (directory)
  |   \-- www    (subvolume root directory, to be mounted at /var/www)
  \-- postgres   (subvolume root directory, to be mounted at /var/lib/postgresql)

Nested:

toplevel                  (volume root directory, to be mounted at /)
+-- home                  (subvolume root directory)
+-- var                   (subvolume root directory)
    +-- www               (subvolume root directory)
    +-- lib               (directory)
         \-- postgresql   (subvolume root directory)

Snapper

Snapper ‒ это утилита для управления снапшотами для LVM и Btrfs.

# Установка
$ yay -S snapper

# Глобальные настройки
$ sudoedit /etc/conf.d/snapper

$ cd /etc/snapper/config-templates
$ sudo cp default custom

# Снапшоты делаются через промежуток времени, заданный в юните systemd
$ sudo systemctl cat snapper-timeline.timer
# /usr/lib/systemd/system/snapper-timeline.timer

[Unit]
Description=Timeline of Snapper Snapshots
Documentation=man:snapper(8) man:snapper-configs(5)

[Timer]
OnCalendar=hourly

[Install]
WantedBy=timers.target

# при необходимости меняем значение таймера
$ sudo systemctl edit snapper-timeline.timer

[Timer]
OnCalendar=<новое значение>

# По-умолчанию snapper хранит снапшоты слишклм долго
$ sudoedit custom

# Храним удаленные файлы неделю, после чего их восстановить уже не получится
...
TIMELINE_LIMIT_HOURLY="24" 
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="0" 
TIMELINE_LIMIT_MONTHLY="0"
TIMELINE_LIMIT_YEARLY="0"
...

# Помощь по настройкам
man snapper-configs

# Создаем конфиги для каждого подраздела отдельно, используя конфиг custom
$ sudo snapper -c root create-config -t custom /
$ sudo snapper -c home create-config -t custom /home

# Сгенерированные шаблоны находятся в /etc/snapper/configs

# Список конфигов
$ sudo snapper list-configs
Config | Subvolume
-------+----------
home   | /home
root   | /

# Созданные конфиги меют такой адрес: /etc/snapper/configs/<config>

# Список снапшотов для конфига
$ snapper -c CONFIG list

# Удаление конфига
$ sudo snapper -c CONFIG delete-config

# Создать новый снапшот
$ sudo snapper -c CONFIG snapshot

# Удалить снапшот
$ sudo snapper -c CONFIG delete N

# Удалить диапазон снапшотов
$ sudo snapper -c CONFIG delete X-Y

# Список созданных/измененных/удаленных файлов
# 0 ‒ это текущий подтом (снапшоты тоже подтома)
$ sudo snapper -c <config> status N..0

# Изменение в файле
$ sudo snapper -c <config> diff N..0 <filename>

# Восстановить файл
$ sudo snapper -c <config> undochanges N..0 <filename>

# Откатиться к снапшоту
$ sudo snapper -c <config> undochanges N..0

# Добавляем .snapshots в исключения для mlocate
$ sudo nano /etc/updatedb.conf
...
PRUNENAMES = ".git .hg .svn .snapshots"
...

# Для KDE
$ vim ~/.config/baloofilerc
...
exclude filters=...,.snaphots
...

# Включаем автоматическое создания снапшотов
$ sudo systemctl enable snapper-timeline.timer && sudo systemctl start snapper-timeline.timer

# Можно так же периодичность очистки снапшотов изменить:

$ sudo systemctl edit snapper-cleanup.timer

# /etc/systemd/system/snapper-cleanup.timer.d/override.conf
# [Timer]
# OnUnitActiveSec=1h

# Автоматически  удаляет снапшоты при превышении квот
$ sudo systemctl enable snapper-cleanup.timer && sudo systemctl start snapper-cleanup.timer

# Просмотр логов
$ tail -f /var/log/snapper.log

Ссылки:

Timeshift

Программа для управления бекапами. Работает с Btrfs и в rsync-режиме (полный дамп).

$ yay -S timeshift

Логи

# Как посмотреть логи?
$ less /var/log/messages
$ more -f /var/log/messages
$ cat /var/log/messages
$ tail -f /var/log/messages
$ grep -i error /var/log/messages

# Сообщения ядра Linux
$ dmesg | less
Файл Описание
/var/log/messages General message and system related stuff
/var/log/auth.log Authenication logs
/var/log/kern.log Kernel logs
/var/log/cron.log Crond logs (cron job)
/var/log/maillog Mail server logs
/var/log/qmail/ Qmail log directory (more files inside this directory)
/var/log/httpd/ Apache access and error logs directory
/var/log/lighttpd/ Lighttpd access and error logs directory
/var/log/boot.log System boot log
/var/log/mysqld.log MySQL database server log file
/var/log/secure or /var/log/auth.log Authentication log
/var/log/utmp or /var/log/wtmp Login records file
/var/log/yum.log Yum command log file.

Установка и настройка Postgres

[sergey@sergey-pc ~]$ sudo pacman -S postgresql
[sergey@sergey-pc ~]$ sudo chown postgres /var/lib/postgres/data
[sergey@sergey-pc ~]$ sudo -i -u postgres
[postgres@sergey-pc ~]$ initdb  -D '/var/lib/postgres/data'
[postgres@sergey-pc ~]$ logout
[sergey@sergey-pc ~]$ sudo systemctl start postgresql
[sergey@sergey-pc ~]$ sudo systemctl enable postgresql
[sergey@sergey-pc ~]$ sudo -u postgres -i initdb --locale $LANG -E UTF8 -D /var/lib/postgres/data
[sergey@sergey-pc ~]$
[postgres@sergey-pc ~]$ createuser --interactive -P
Enter name of role to add: sergey
Enter password for new role:
Enter it again:
Shall the new role be a superuser? (y/n)
Please answer "y" or "n".
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) y
[postgres@sergey-pc ~]$ createdb -O sergey sergey # создаем пользователя и БД с именами совпадающими с пользователем системы, чтобы psql запускать без параметров
[postgres@sergey-pc ~]$ logout
[sergey@sergey-pc ~]$ psql
psql (11.1)
Type "help" for help.

sergey=>

# Дамп базы схемы БД
$ pg_dump -d db -f /tmp/dump.sql
# Загрузка дампа
$ psql db < /tmp/dump.sql

Мониторинг процессов

# Замена стандартному top
$ yay -S htop
$ htop

systemd

# Все сервисы

# Покажут только включенные
$ systemctl
$ systemctl list-units --type service

# + выключенные
$ systemctl list-unit-files --type service

$ sudo systemctl enable docker

$ sudo systemctl disable docker

$ sudo systemctl restart nginx.service

$ sudo systemctl start application.service

$ sudo systemctl start application.service

$ systemctl status nginx.service

$ sudo systemctl is-enabled service

Создание своего сервиса:

/etc/systemd/system/rot13.service:

[Unit]
Description=ROT13 demo service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=centos
ExecStart=/usr/bin/env php /path/to/server.php

[Install]
WantedBy=multi-user.target

Ссылки:

Git

# Установка
$ yay -S git

# Глобальные настройки
$ git config --global user.name <yourname>
$ git config --global user.email <email>

# Цветной вывод
$ git config --global color.ui true

# Сменить ветку
$ git checkout <branchname>

# Создать ветку и переключится на нее
$ git checkout -b <branchname>

# Объединить текущую ветку с branchname
$ git merge <branchname>

# Добавить изменения (все файлы в каталоге и вложеннхы)
$ git add .

# Закоммитить изменения (сделать описание)
$ git commit -m "Тест"

# Если не были добавлены новые файлы, а лишь производились изменения в уже добавленных, то можно использовать только одну команду
$ git commit -am "Тест"

# Обновить репозиторий на сервере
$ git push

# Выгрузить изменения с сервера (тоже самое, что git fetch + git merge)
$ git pull

# Копировать репозиторий
$ git clone https://github.com/someuser/repo.git [<assigneddirectory>]

# Посмотреть историю
$ git log --graph --oneline --decorate --all

# Посмотреть отличия по сравнения с предыдущей версией
$ git diff 871d36b [<filename>]

# Сохранить изменения
$ git stash [save "my stash message here"]

# Удалить stach и применить его
$ git stash pop [stash@{1}]

# Список stash
$ git stash list

# Посмотреть что там лежит
$ git stash show stash@{0}

$ git stash apply
$ git stash drop stash@{2}
$ git stash clear

# List all the tags:

$ git tag

# Search tags for a particular pattern:

$ git tag -l <tag-pattern>

# Show a tag data:

$ git show <tag-name>

# Create a Lightweight Tag:

$ git tag <tag-name>

# Create an Annotated Tag:

$ git tag -a <tag-name> -m <tag-message>

# Create a tag for a specific commit:

$ git tag -a <tag-name> <commit-checksome>

# Push a specific tag to remote:

$ git push origin <tag-name>

# Push all the tags to remote:

$ git push origin --tags

# Checkout a specific to local:

$ git checkout -b <branch-name> <tag-name>

Работаем с github через ssh

Генерация нового ключа:

$ ssh-keygen -t rsa -b 4096 -C "<email>"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/sergey/.ssh/id_rsa): /home/sergey/.ssh/github_rsa
Created directory '/home/sergey/.ssh'.
...

В настройках нужно добавить сгенерированный ключ, скопировав содержимое pub-файла (для примера - github_rsa.pub), который лежит в ~/.ssh.

Если уже есть проекты, которые были ранее склонированы по https, то нужно изменить .git/config проекта. :

...
[remote "origin"]
url = git@github.com:<username>/<project>.git
...

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

image

Для проекта можно указать локальные email и имя:

git config user.email <email>
git config user.name <name>

Tor Service

Включаем Tor:

sudo systemctl start tor
sudo systemctl enable tor

Проверка:

$ torify curl http://httpbin.org/ip
{
  "origin": "173.244.209.5, 173.244.209.5"
}

Менеджер паролей pass

$ yay -S pass
# Далее нужно сгенерировать PGP ключ. Сгенерированный ключ можно удалить через seahorse
$ gpg2 --gen-key
gpg (GnuPG) 2.2.16; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: Sergey M
Email address: tz4678@gmail.com
You selected this USER-ID:
    "Sergey M <tz4678@gmail.com>"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 82AD537DDC8DD344 marked as ultimately trusted
gpg: revocation certificate stored as '/home/sergey/.gnupg/openpgp-revocs.d/<gpg_id>.rev'
public and secret key created and signed.

pub   rsa2048 2019-07-13 [SC] [expires: 2021-07-12]
      <gpg_id>
uid                      Sergey M <tz4678@gmail.com>
sub   rsa2048 2019-07-13 [E] [expires: 2021-07-12]

# Теперь инициализируем хранилище
$ pass init gpg_id

# Можем сгенерировать пароль (будет автоматически сохранен)
$ pass generate example.com 15
The generated password for example.com is:
'.kXKEs<lx4dcKM

# Посмотреть пароль (потребует passphrase)
$ pass example.com
'.kXKEs<lx4dcKM

# Копировать пароль в буфер обмена
$ pass -c example.com
Copied example.com to clipboard. Will clear in 45 seconds.

# Удалить пароль
$ pass rm example.com
Are you sure you would like to delete example.com? [y/N] y
removed '/home/sergey/.password-store/example.com.gpg'

Базу паролей можно разместить на Google Диск.

Ссылки:

Частые проблемы

Система не грузится дальше rootfs

Нужно пофиксить разделы:

fsck -y <device>

Пример: у нас на диске есть два ntfs раздела раздела, а за ними идет раздел Linux, мы в Windows удаляем ntfs-2, а размер ntfs-1 увеличиваем на все освободившееся пространство, в итоге Windows выходит за свои границы и портит раздел Linux. Вывод: нужно между разделами Windows и Linux оставлять пару мегабайт свободного места.

Grub Rescue

Чаще всего эта ошибка происходит после переименования логических разделов LVM, подразделов Btrfs, переноса системы на новый раздел (когда не совпадают GUID'ы).

error: ... not found.
Entering rescue mode...

# Для начала нужно посмотреть все устройства и разделы
grub rescue> ls
(hd0) (hd1) (hd1,gpt1) (hd2) (hd2,gpt5) (hd2,gpt4) (hd2,gpt3) (hd2,gpt2) (hd2,gpt1) (hd3,gpt2) (hd3,gpt1) (hd4) (hd5)

# Мы помним, что наша система находится на 5 разделе, так что тут гадать не нужно
grub rescue> set prefix=(hd2,gpt5)/@/boot/grub
# «@» ‒ это имя подраздела Btrfs. Для обычного Ext4 раздела, команда будет выглядеть так:
#
#   set prefix=(hd2,gpt5)/boot/grub
#
# А для LVM:
#
#  set prefix=(lvm/arch-root)/boot/grub
grub rescue> set root=(hd2,gpt5)

# Проверим
grub rescue> ls /
@/ @home

# Да, это наш корневой раздел Linux
# Теперь можно загрузиться в систему
grub rescue> insmod normal
grub rescue> normal

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

$ sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id="Arch Linux"
$ sudo grub-mkconfig -o /boot/grub/grub.cfg

Случайно нажали Ctrl + Alt + F* и экран стал темным

Это переключение между виртуальными терминалами. с 1-6 текстовые, остальные ‒ графические. В gdm Ctrl+Alt+F1 ‒ логин в систему, Ctrl+Alt+F2 ‒ рабочий стол. В lightdm переключиться на рабочий стол можно нажатием Ctrl+Alt+F7.

Что делать, если каталоги открываются в VSCode?

Существует файл /usr/share/applications/mimeinfo.cache. В нем хранятся ассоциации между mime-типами и приложениями. Его редактирование исправляет проблему, НО такое решение является временным, так как этот файл генерируется при каждом обновлении системы из *.desktop файлов.

Нужно отредактировать MimeType (я его просто закомментировал) в /usr/share/applications/visual-studio-code.desktop и обновить mimeinfo.cache:

$ sudo nano /usr/share/applications/visual-studio-code.desktop
...
# MimeType=text/plain;inode/directory;
...
$ sudo update-desktop-database /usr/share/applications

Enter password to unlock your login keyring

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

Решение:

# можно нажать `Super+A` и поискать приложение `passwords and keys`
$ seahorse &

# Если пакет не установлен
$ yay -S seahorse

image

Удаляем вкладку Login:

image

Другой вариант удалить все кейринги вручную:

$ rm -rf ~/.local/share/keyrings

Далее удаляем настройки Chrome:

$ rm -rf ~/.config/google-chrome

Теперь остается только перезапустить Chrome.

Это окошко появляется, в случае если пароль от keyring не совпадает с паролем пользователя.

Ставим менеджер паролей:

$ yay -S seahorse

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

Справка по командам и т.д.

Cheat.sh

Ищет на stackoverflow и других ресурсах справку по командам и языкам программирования.

Установка:

curl https://cht.sh/:cht.sh | sudo tee /usr/local/bin/cht.sh
sudo chmod +x /usr/local/bin/cht.sh

# Так же требуются пакеты xsel и rlwrap
yay -S xsel rlwrap

Использование:

# Интерактивный режим
$ cht.sh --shell <language>
$ cht.sh --shell bash
type 'help' for the cht.sh shell help
cht.sh/bash> for
# shell - Bash 'for' loop syntax?
#
# Replace

for (($i=0...

# with

for ((i=0;i<10;i++))

# [jman] [so/q/6854118] [cc by-sa 3.0]
cht.sh/bash>

$ cht.sh go create file
/*
 * go - Create an empty text file
 *
 * Don't try to check the existence first, since you then have a race if
 * the file is created at the same time. You can open the file with the
 * O_CREATE flag to create it if it doesn't exist:
 */

os.OpenFile(name, os.O_RDONLY|os.O_CREATE, 0666)

// [JimB] [so/q/35558787] [cc by-sa 3.0]

# Небольшой туториал по языку
$ cht.sh python :learn

Marker

Установка:

$ git clone --depth=1 https://github.com/pindexis/marker ~/.marker && ~/.marker/install.py
  • Ctrl-space: search for commands that match the current written string in the command-line.
  • Ctrl-k (or marker mark): Bookmark a command.
  • Ctrl-t: place the cursor at the next placeholder, identified by '{{anything}}'
  • marker remove: remove a bookmark

image

Пользовательские команды хранятся в ~/.local/share/marker/user_commands.txt.

Пример:

yay -S {{package}}##install package
yay -S --noconfirm {{package}}##install package without confirmations
yay -Ss {{search}}##search packages
yay -Si {{package}}##package information
yay -Sc##clean
yay -Syu##update all packages
yay -Ps##print system stats
yay -Pu##print list of packages that needs to be updated
yay -Rns {{package}}##remove package
exec "$SHELL"##reload shell

"Встроенные" в /home/sergey/.marker/tldr/.

TLDR

Этим я пользовался до cht.sh.

$ npm i tldr -g

Получаем краткую справку по команде:

$ tldr nvm
✔ Page not found. Updating cache...
✔ Creating index...

  nvm

  Install, uninstall or switch between Node.js versions.
  Supports version numbers like "0.12" or "v4.2", and labels like "stable", "system", etc.
  Homepage: https://github.com/creationix/nvm.

  - Install a specific version of Node.js:
    nvm install node_version

  - Use a specific version of Node.js in the current shell:
    nvm use node_version

  - Set the default Node.js version:
    nvm alias default node_version

  - List all available Node.js versions and highlight the default one:
    nvm list

  - Uninstall a given Node.js version:
    nvm uninstall node_version

  - Launch the REPL of a specific version of Node.js:
    nvm run node_version --version

  - Execute a script in a specific version of Node.js:
    nvm exec node_version node app.js

Шпаргалка по командам Shell

# ==============================================================================
#
# Основы синтаксиса
#
# ==============================================================================

# $1, $2, $3, ... are the positional parameters.
# "$@" is an array-like construct of all positional parameters, {$1, $2, $3 ...}.
# "$*" is the IFS expansion of all positional parameters, $1 $2 $3 ....
# $# is the number of positional parameters.
# $- current options set for the shell.
# $$ pid of the current shell (not subshell).
# $_ most recent parameter (or the abs path of the command to start the current shell immediately after startup).
# $IFS is the (input) field separator.
# $? is the most recent foreground pipeline exit status.
# $! is the PID of the most recent background command.
# $0 is the name of the shell or shell script.

# присвоить значение переменной
x=42

# Для вывода используем echo и printf
echo "x=$x"
echo "x=${x}"
printf "x=%s\n" x

# Если переменная не задана, то присваиваем ей дефолтное значение
x=${x:-default}

# $ { varname :- word }
# If varname exists and isn’t null, return its value; otherwise return word.

# Purpose:
# Returning a default value if the variable is undefined.

# Example:
# ${count:-0} evaluates to 0 if count is undefined.

# $ { varname := word}
# If varname exists and isn’t null, return its value; otherwise set it to word and then return its value. Positional and special parameters cannot be assigned this way.

# Purpose:
# Setting a variable to a default value if it is undefined.

# Example:
# $ {count := 0} sets count to 0 if it is undefined.

# $ { varname :? message }
# If varname exists and isn’t null, return its value; otherwise print varname : followed by message, and abort the current command or script (non-interactive shells only). Omitting message produces the default message parameter null or not set.

# Purpose:
# Catching errors that result from variables being undefined.

# Example:
# {count :?” undefined! " } prints “count: undefined!” and exits if count is undefined.

# $ { varname :+word }
# If varname exists and isn’t null, return word; otherwise return null.

# Purpose:
# Testing for the existence of a variable.

# Example:
# $ {count :+ 1} returns 1 (which could mean “true”) if count is defined.


# $ { varname : offset }
# $ { varname : offset:length }

# Purpose:
# Returning parts of a string (substrings or slices).

# Example:
# If count is set to frogfootman, $ {count :4} returns footman. $ {count :4:4} returns foot.

# Экспорт глобальной переменной
export VAR=42

# Генерация строк с помощью Brace expansion
$ echo a{d,c,b}e
ade ace abe

# Массивы

arr=(Hello World)

echo ${arr[0]} ${arr[1]}

${arr[*]} # Все записи в массиве
${!arr[*]} # Все индексы в массиве
${#arr[*]} # Количество записей в массиве
${#arr[0]} # Длина первой записи (нумерация с нуля)

array=(one two three four [5]=five)

echo "Array size: ${#array[*]}"  # Выводим размер массива

echo "Array items:" # Выводим записи массива
for item in ${array[*]}
do
  printf "   %s\n" $item
done

echo "Array indexes:" # Выводим индексы массива
for index in ${!array[*]}
do
  printf "   %d\n" $index
done

echo "Array items and indexes:" # Выводим записи массива с их индексами
for index in ${!array[*]}
do
  printf "%4d: %s\n" $index ${array[$index]}
done

# Следующий пример покажет, как кавычки и конструкции без кавычек возвращают строки (особенно важно, когда в этих строках есть пробелы):

array=("first item" "second item" "third" "item")

echo "Number of items in original array: ${#array[*]}"
for ix in ${!array[*]}
do
  printf "   %s\n" "${array[$ix]}"
done
echo

arr=(${array[*]})
echo "After unquoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
  printf "   %s\n" "${arr[$ix]}"
done
echo

arr=("${array[*]}")
echo "After * quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
  printf "   %s\n" "${arr[$ix]}"
done
echo

arr=("${array[@]}")
echo "After @ quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
  printf "   %s\n" "${arr[$ix]}"
done

# Циклы

for i in $(seq 1 10);
do
  echo $i
done

for ((i = 0 ; i < max ; i++ ))
do
  echo $i
done

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

for w in word1 word2 word3
do
  doSomething($w)
done

# А вот это zsh не умеет!
for filename in *.sh
  echo "$filename"
end

i=0
while (( ++i <= num )); do
  printf 'counter is at %d\n' "$i"
done

i=1
while [ "$i" -le "$num" ]; do
  printf 'counter is at %d\n' "$i"
  i=$(( i + 1 ))
done

# Условия

if [ "$seconds" -eq 0 ]; then
  timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
  timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
  echo "Unknown parameter"
fi

# В условиях нужно использовать двойные скобки

# [ is just a regular command with a weird name.
# ] is just an argument of [ that prevents further arguments from being used.

# [[ a = a && b = b ]]: true, logical and
# [ a = a && b = b ]: syntax error, && parsed as an AND command separator cmd1 && cmd2just an argument of [ that prevents further arguments from being used.

# x='a b'; [[ $x = 'a b' ]]: true, quotes not needed
# x='a b'; [ $x = 'a b' ]: syntax error, expands to [ a b = 'a b' ]

# Подробнее тут:
#   <https://stackoverflow.com/a/47576482>

# -eq
# is equal to

[ "$a" -eq "$b" ]

# -ne
# is not equal to

[ "$a" -ne "$b" ]

# -gt
# is greater than

[ "$a" -gt "$b" ]

# -ge
# is greater than or equal to

[ "$a" -ge "$b" ]

# -lt
# is less than

[ "$a" -lt "$b" ]

# -le
# is less than or equal to

[ "$a" -le "$b" ]

# <
# is less than (within double parentheses)

(("$a" < "$b"))

# <=
# is less than or equal to (within double parentheses)

(("$a" <= "$b"))

# >
# is greater than (within double parentheses)

(("$a" > "$b"))

# >=
# is greater than or equal to (within double parentheses)

(("$a" >= "$b"))

# <http://tldp.org/LDP/abs/html/comparison-ops.html>

# [ ‒ это всего лишь команда, последним аргументом которой всегда должна быть "]"! Все операторы описаны в man'е:
man [

# Это вполне себе валидное выражение
"[" 1 -eq 0 "]" || echo fail

# Строка слева всегда имя переменной
x=42; [[ "x" -eq "42" ]] || echo fail

# выражение слева всегда переменная

case $VAR in
  foo) ... ;;
  bar) ... ;;
  # Все остальные значения
  *) ... ;;
esac

# Объявление функции
foo() {
  # Аргументы функции
  $1..$N
  # Локальная переменная
  local x=42
  ...
  # Теперь в $1 будет $2, в $2 ‒ $3 и т.д.
  shift
}

# Экспорт функции
export -f foo

die() { echo "$*" 1>&2 ; exit 1; }
...
die "Kaboom"

[ "$#" -eq 2] || die "Needs 2 arguments, input and output"

# The syntax is token-level, so the meaning of the dollar sign depends on the token it's in. The expression $(command) is a modern synonym for `command` which stands for command substitution; it means, run command and put its output here. So

echo "Today is $(date). A fine day."

# Управление выводом

# Направить stdout одной программы в stdin другой
command1 | command2

# Перенаправление stdout и stderr
command1 |& command2

# Создать либо перезаписать файл, добавив строку
command > out

# Создать файл, если его не существует и дописать строку в конец
command >> out

# Направить stderr команды в файл
command 2>&1 out

# stdout 2-ой команды, является stdin для первой
command1 <<< command2

# Вывод многострочного текста
cat <<EOF
хуй
пизда
джигурда
EOF

cat >> /path/to/file <<EOL
хуй
пизда
джигурда
EOL

# ==============================================================================
#
# Написание скриптов
#
# ==============================================================================

# Первой строкой скрипта идет Shebang, торый указывает какой интерпретатор использовать

#!/usr/bin/env bash

# При наличии ошибок прекратит выполнение сценария
set -e

# Так же часто делают каталог скрипта рабочим (по-умолчанию рабочим является тот откуда запустили скрипт)
cd "$(dirname "$0")"

# ==============================================================================
#
# Выполнение скриптов
#
# ==============================================================================

# Сделать файл исполняемым
$ chmod +x /path/to/file

# Выполнит скрипт в текущем процессе (переменные и функции, объявленные внутри скрипта станут доступны в терминале)
$ source /path/to/file

# ==============================================================================
#
# Запуск команд
#
# ==============================================================================

# Запустить процесс и вернуть его дескриптор (при закрытии терминала будет остановлена)
$ command &

# То же самое за исключением того, что процесс не будет остановлен при закрытии терминала
$ nohup command &

# ==============================================================================
#
# Пакеты
#
# ==============================================================================

# Установить пакет
$ yay -S <package>

# Удалить пакет
$ yay -Rns <package>

# Обновить все установленные пакеты
$ yay -Syu

# Обновить в т.ч. с пакетами для разработчика
$ yay -Syu --devel --timeupdate

# Очистить кеш
$ yay -Sc

# Удалить все ненужные зависимости
$ yay -Yc

# Статистика по пакетами
$ yay -Ps

# Generates development package DB used for devel updates
$ yay -Y --gendb

# Ошибки с удалением зависимостей

$ yay -Rns gnome-extra
checking dependencies...
error: failed to prepare transaction (could not satisfy dependencies)
:: nautilus: removing nautilus-sendto breaks dependency 'nautilus-sendto'
$ yay -Rdd nautilus-sendto

# Теперь можно снести gnome-extra

# ==============================================================================
#
# Текст
#
# ==============================================================================

# Замена в тексте
$ echo "This is a test" | sed 's/test/another test/'

# Ключ -e позволяет выполнить несколько команд:
#   sed -e 's/This/That/; s/test/another test/'

# Перевод регистра
$ echo lowercase | tr '[:lower:]' '[:upper:]'
LOWERCASE

# ==============================================================================
#
# Файловая система
#
# ==============================================================================

# Список разделов
$ sudo fdisk -l

$ sudo mkdir /mnt/usb1
# Монтировать устройство
$ sudo mount /dev/sdb1 /mnt/usb1

# Размонтируем устройство
$ sudo umount /dev/sdb1
# или
$ sudo umount /mnt/usb1

# Сменить владельца и группу для файла
$ sudo chown $USER:$USER /path/to/file

# В Linux все файлы. Регулярные файлы ‒ обычные файлы, каталоги ‒ это файлы содержащие список файлов и т.д.

# Перемещение/переименование файла
$ mv <src> <dst>

# Копирование файлов
$ cp <src> <dst>

# Копировать каталог и все вложенные файлы
$ cp -r <src> <dst>

# Полный путь до файла
$ realpath example.txt
/home/username/example.txt

# Листинг каталога
$ ls
$ tldr ls

# Вывести информацию о владельце и группе файла
$ ls -ld /path/to/file
$ stat /path/to/file

# Вывести все вложенные файлы
$ ls -R <path>
$ find <path> -print

# Покажет имя и размер
$ du -a <path>

# Размер всех файлов с расширеним .txt
$ du -chs *.txt

# Создание каталога
$ mkdir <target>

# Создание каталога вместе с родительскими каталогами, если тех не существует
$ mkdir -p <target>

# Создать каталог с определенными правами
$ mkdir -m 0750 <directory>

# Создание множества каталогов
$ mkdir foo bar baz
# или
$ mkdir prefix-{foo,bar,baz}

# Такой же трюк работает при создании файлов
$ touch {foo,bar,baz}.txt

# Создать мягкую ссылку на файл либо заменить ее новой
$ ln -sf path/to/new_file path/to/symlink

# Мягкая ссылка содержит путь до файла. Жесткая ссылается на inode, искомый
# файл при перемещении остается доступен по ссылке и невозможно ссылаться на
# файл на другом устройстве

# Слияние файлов в один
$ paste file1.txt file2.txt > fileresults.txt

# Удалить файлы старше 5 дней
$ find /path/to/files* -mtime +5 -exec rm {} \;

# Удалить все шрифты соответствущие шаблону *powerline* без учета регистра
# «{} \;» rm будет вызван множество раз
# «{} +» добавляет агрументы к rm
$ sudo find /usr/share/fonts -iname "*powerline*" -exec rm {} +

# Поиск фала по имени в специальной базе
$ locate -e login.keyring
/home/sergey/.local/share/keyrings/login.keyring

# Установка
$ yay -S mlocate

# Перед первым запуском следует выполнить
$ sudo updatedb

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

# Стастика
$ locate -S
Database /var/lib/mlocate/mlocate.db:
	157 512 directories
	1 384 522 files
	119 423 666 bytes in file names
	38 722 751 bytes used to store database

# Поиск исполняемых файлов, исходников и страниц манула
$ whereis <q>

# Покажет что куда смонтировано (можно свободное место узнать)
$ df -h --total

# Узнать на каком разделе смонтирован каталог
$ df -h /tmp

# Просмотр числа inode
$ df -i

# Просмотр содержимого фйала с навигацией
$ less /path/to/file

# или более короткая версия в ZSH
$ < /path/to/file

# Просмотр логов в реальном времени
$ tail -f /var/log/syslog | less

# Вывести строки не соответствующие шаблону
$ grep -Pv <exclude_pattern> <filename>

# Создать файл, забитый null-байтами
$ dd if=/dev/zero of=/tmp/nullbytes bs=1M count=1

# Конфертировать .md в .rst
$ pip install m2r
$ m2r --help

# Конвертировать .webp в .png
$ yay -S libwebp
$ dwebp file.webp -o file.png

# Вывод содержимого файла с подсветкой синтаксиса
$ yay -S ccat
$ ccat ./file

# Вывести файлы в каталоге, отсортировав их по времени до доступа
$ ls -ltu <path>

# Изменить размер каталога /tmp
$ mount -o remount,size=4G /tmp/

# Подробная информация о диске
$ sudo smartctl -a /dev/nvme0

# ==============================================================================
#
# Работа с архивами
#
# ==============================================================================

# Заархивировать каталог
$ tar -czvf filename.tar.gz directory

# Для извлечения файлов проще всего пользоваться плагином Oh My ZSH extract

# Извлечь архив и удалить его (ключ -r)
$ extract -r <filename>

# Извлечь .tar.gz
$ tar zxvf <yourfile>.tar.gz -C /usr/src/

# Скачать и Распаковать Архив с помощью WGET
$ wget http://example.com/archive.tar -O - | tar -x
$ wget http://example.com/archive.tar.gz -O - | tar -xz
$ wget http://example.com/archive.tar.bz2 -O - | tar -xj

# Скачать и Распаковать Архив с помощью CURL
$ curl http://example.com/archive.tar | tar -x
$ curl http://example.com/archive.tar.gz | tar -xz
$ curl http://example.com/archive.tar.bz2 | tar -xj

# ==============================================================================
#
# Сеть
#
# ==============================================================================

# Показать все прослушиваемые и установленные порты TCP и UDP вместе с PID
# связанного процесса
$ netstat -plantu

# Все запущенные сервера на хосте
$ netstat -lnt

# Скачать файл в каталог
$ wget -P $ZSH_CUSTOM/themes https://raw.githubusercontent.com/caiogondim/bullet-train-oh-my-zsh-theme/master/bullet-train.zsh-theme

# ==============================================================================
#
# Шрифты
#
# ==============================================================================

# Список установленных шрифтов
$ fc-list

# Обновить базу шрифтов после добавления/удаления их в/из `/usr/share/fonts`
# либо `~/.local/share/fonts`
$ fc-cache -f -v

# ==============================================================================
#
# Буфер обмена
#
# ==============================================================================

$ yay -S xclip

# Скопировать текст в буфер обмена
$ echo 123 | xclip -sel clip

# Копировать содержимое файла в буфер обмена
$ xclip -sel clip < ~/.ssh/github_rsa.pub

# Вывести содержимое буфера обмена
$ xclip -o -sel clip

# Конвертировать файл в base64 и скопировать в буфер обмена
$ file="test.docx"
$ base64 -w 0 $file  | xclip -selection clipboard


# ==============================================================================
#
# Языковые настройки
#
# ==============================================================================

# Список влюченных локалей
$ locale -a

# Добавление локалей

# В этом файле находится список всех поддерживаемых локалей
# Раскомментируем нужную
$ sudo nano /etc/locale.gen

# Генерируем локали
$ sudo locale-gen

# Можно так же локали так добавлять
$ sudo locale-gen de_DE.UTF-8

# Меняем язык системы (нужно перегрузиться)
echo "LANG=de_DE.UTF-8" > /etc/locale.conf

# ==============================================================================
#
# Генерация паролей
#
# ==============================================================================

$ yay -S pwgen
$ pwgen -cnsy 10 1
1u_dr<ZLH;

$ pip install xkcdpass
$ xkcdpass -n 3 -d -
backdrop-unruly-yodel
$ xkcdpass -n 3 -d - --min 2 --max 6
shrank-trio-thong

# ==============================================================================
#
# Прочее
#
# ==============================================================================

# Перегрузить Shell
$ exec "$SHELL"

# Список всех доступных команд
$ compgen -c

# Ищем Chrome
$ compgen -c | grep chrome
google-chrome-stable
chrome-gnome-shell
google-chrome

# Просмотр логов в реальном времени
$ journalctl -f

# Изменить размер терминала
$ gnome-terminal --geometry 135x45

# Документация по командам
$ tldr cat
$ tldr --search create file

Ссылки:


i3: Введение

i3 – это тайловый оконный менеджер для Linux. Тут настройки под меня.

i3: Установка и настройка

$ yay -S awesome-terminal-fonts bumblebee-status compton fonts-powerline dmenu i3-gaps i3lock-fancy-git lxappearance nitrogen rofi scrot termite xclip
$ sudo nano /usr/share/xsessions/i3-custom.desktop
[Desktop Entry]
Name=i3 custom
Exec=/usr/local/bin/i3-custom
Type=Application
$ sudo nano /usr/local/bin/i3-custom
#!/bin/bash
mkdir -p ~/.config/i3/logs
export TERMINAL=termite
exec i3 -V >> ~/.config/i3/logs/$(date +'%F-%T').log 2>&1
$ sudo chmod +x /usr/local/bin/i3-custom
$ i3-config-wizard
$ cp /etc/xdg/termite/config ~/.config/termite/config
$ nano ~/.config/termite/config
[options]
# ...
font pango:Inconsolata, Font Awesome 10
# ...
[colors]
# ...
# 20% background transparency (requires a compositor)
background = rgba(63, 63, 63, 0.8)
$ cp /etc/xdg/compton.conf ~/.config
$ nano ~/.config/i3/config
# ...
font pango:Droid Sans 10
# ...
# Заменяем все Mod1 на $m и создаем переменную выше вызовов bindsym
set $m Mod1

# lockscreen
bindsym Ctrl+$m+l exec i3lock

# Pulse Audio controls
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +5% #increase sound volume
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -5% #decrease sound volume
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle # mute sound

# Sreen brightness controls
bindsym XF86MonBrightnessUp exec xbacklight -inc 20 # increase screen brightness
bindsym XF86MonBrightnessDown exec xbacklight -dec 20 # decrease screen brightness

# Touchpad controls
bindsym XF86TouchpadToggle exec /some/path/toggletouchpad.sh # toggle touchpad

# Media player controls
bindsym XF86AudioPlay exec playerctl play
bindsym XF86AudioPause exec playerctl pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous

# rofi
bindsym $m+t exec "rofi -combi-modi window,drun -show combi"

# захватывает весь экран и копирует в буфер обмена
bindsym --release Print exec "scrot /tmp/%F_%T_$wx$h.png -e 'xclip -selection c -t image/png < $f && rm $f'"
# захватывает область экрана и копирует в буфер обмена
bindsym --release Shift+Print exec "scrot -s /tmp/%F_%T_$wx$h.png -e 'xclip -selection c -t image/png < $f && rm $f'"
# ...
bar {
  set $disk_format "{path}: {used}/{size}"
  status_command bumblebee-status -m nic disk:root disk:home cpu memory sensors pulseaudio datetime layout pacman -p root.left-click="nautilus /" root.format=$disk_format home.path=/home home.left-click="nautilus /home" home.format=$disk_format -t solarized-powerline
  position top
}
# ...
# отступы между окнами
gaps outer -10
gaps inner 20

floating_minimum_size 75 x 50
floating_maximum_size -1 x -1
# Убрать рамки у окон:
# 1)
# new_window pixel 0
# 2)
# for_window [class="^.*"] border none
# force floating for all new windows
# for_window [class=".*"] floating enable
for_window [class="Nautilus" instance="file_progress"] floating enable
for_window [class="^Telegram"] floating enable, resize set 800 600
# Всплывающие окна браузера
for_window [window_role="pop-up"] floating enable
# no_focus [window_role="pop-up"]
# прозрачность терминала
exec --no-startup-id compton --config ~/.config/compton.conf
# смена расскладки
exec --no-startup-id setxkbmap -model pc105 -layout us,ru -option grp:ctrl_shift_toggle
# восстановление заставки рабочего стола
exec --no-startup-id nitrogen --restore

Нужно выйти из сессии и выбрать в Display Manager сессию i3 custom.

LXAppearance используется для изменения значков, шрифта по-умолчанию в приложениях.

Nitrogen позволяет менять обои.

Для изменения оформления i3 – служит i3-style:

$ yay -S i3-style
$ i3-style archlinux -o ~/.config/i3/config --reload

XTerm

Вместо Ctrl+Shift+V нужно использовать Shift+Ins, а вместо Ctrl+Shift+CCtrl+C. Права кнопка мыши копировать, клик по колесику – вставить.

Termite: горячие клавиши

Сочетание Значение
ctrl-shift-x activate url hints mode
ctrl-shift-r reload configuration file
ctrl-shift-c copy to CLIPBOARD
ctrl-shift-v paste from CLIPBOARD
ctrl-shift-u unicode input (standard GTK binding)
ctrl-shift-e emoji (standard GTK binding)
ctrl-tab start scrollback completion
ctrl-shift-space start selection mode
ctrl-shift-t open terminal in the current directory [1]_
ctrl-shift-up scroll up a line
ctrl-shift-down scroll down a line
shift-pageup scroll up a page
shift-pagedown scroll down a page
ctrl-shift-l reset and clear
ctrl-+ increase font size
ctrl-- decrease font size
ctrl-= reset font size to default

Отсюда.

Termite: цветовые схемы

$ curl https://raw.githubusercontent.com/khamer/base16-termite/master/themes/base16-nord.config >> ~/.config/termite/config
$ nano ~/.config/termite/config
# 4-ое значение отвечает за прозрачность (1 - непрозрачно, 0 - абсолютная прозрачность)
background          = rgba(40, 44, 52, 0.8)

i3: заставка lockscreen

$ yay -S i3lock-fancy-git
$ nano ~/.config/i3/config
# параметр -B делает фоном lockscreen скриншот экрана с размытием
bindsym Ctrl+$m+l exec i3lock-fancy -gpf Ubuntu -- scrot -z

Репозиторий.

i3: сохранение/восстановление рабочего пространства

# Сохранение
i3-save-tree --workspace 1 > ~/.i3/workspace-1.json
# Восстановление
i3-msg "workspace 1; append_layout ~/.i3/workspace-1.json"

Требует установки зависимостей.

Документация.

--

Анимированные обои

$ yay -S komorebi

Видео-инструкция.

Ошибки при установке расширений для Gnome

Посмотрить их можно так:

$ journalctl /usr/bin/gnome-shell -f

Либо можно нажать Alt+F2 и ввести lg и поебаться с консолечкой. Закрыть ее можно с помощью клавиши Esc.

@s3rgeym
Copy link
Author

s3rgeym commented Mar 1, 2023

5.000 слов и 40.000 символов, те это тянет на 20-страничный мануал или 10 листов. Если собрать все мои тексты, то, наверное, получилась бы книга на 100 листов

~ 
❯ wget -qO- https://gist.githubusercontent.com/s3rgeym/bd33f94ab96c96bc6719035fcac2b807/raw/abaa8e4ebef737a4a8bdeebc452249e74cc9b493/Arch-Install-SED-Luks-Btrfs.md | html2text | wc -w
4858

~ 
❯ wget -qO- https://gist.githubusercontent.com/s3rgeym/bd33f94ab96c96bc6719035fcac2b807/raw/abaa8e4ebef737a4a8bdeebc452249e74cc9b493/Arch-Install-SED-Luks-Btrfs.md | wc -m    
39056

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment