Классный скрипт для конвертации в utf8

Запарило пересохранять субтитры, которые часто выкладывают в вин-кодировке. Нашел клевый скрипт на питоне (а значит и под виндой можно юзать) для конвертации из любой кодировки (исходная автоопределяется) в UTF8. Навесил его как кастомную команду для *.srt в Double Commander, который также юзаю в обеих системах — стало совсем хорошо =)

 
 
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. from chardet import detect
  5. srcfile = sys.argv[1]
  6. tmpfile = sys.argv[1] + '.tmp'
  7. bakfile = sys.argv[1] + '.bak'
  8. # get file encoding type
  9. def get_encoding_type(file):
  10.     with open(file, 'rb') as f:
  11.         rawdata = f.read()
  12.     return detect(rawdata)['encoding']
  13. from_codec = get_encoding_type(srcfile)
  14. # add try: except block for reliability
  15. try:
  16.     with open(srcfile, 'r', encoding=from_codec) as f, open(tmpfile, 'w', encoding='utf-8') as e:
  17.         text = f.read() # for small files, for big use chunks
  18.         e.write(text)
  19.     os.rename(srcfile, bakfile) # backup old encoding file
  20.     os.rename(tmpfile, srcfile) # rename new encoding
  21.    
  22. except UnicodeDecodeError:
  23.     print('Decode Error')
  24. except UnicodeEncodeError:
  25.     print('Encode Error')

Сброс пароля на хосте VMware ESXi

Для сброса пароля хоста ESXi понадобится доступ к серверу (физический, или через iLO-подобные системы управления) и Live CD с каким-нибудь линуксом (я использую GParted Live).

1. Загрузившись с Live CD, проверим какие диски и разделы нам доступны. Скорее всего найдется единственный диск с 9-ю разделами на нем

 
 
  1. ls /dev| grep sd
 
 
  1. sda
  2. sda1
  3. sda2
  4. sda3
  5. sda4
  6. sda5
  7. sda6
  8. sda7
  9. sda8
  10. sda9

2. Пароль находится в архиве в архиве (да, два раза) на разделе sda5. Смонтируем раздел и проверим.

 
 
  1. mkdir /mnt/sda5
  2. mount /dev/sda5 /mnt/sda5
  3. ls -l /mnt/sda5/state.tgz
 
 
  1. -rwxr-xr-x 1 root root 12969 Apr 21 10:42 /mnt/sda5/state.tgz

3. Создадим временную директорию и распакуем в нее этот файл

 
 
  1. mkdir /tmp/state
  2. tar -xf /mnt/sda5/state.tgz -C /tmp/state/
  3. # из архива вылез второй архив, распакуем его сюда же
  4. tar -xf /tmp/state/local.tgz -C /tmp/state/
  5. # удалим этот промежуточный архив
  6. rm /tmp/state/local.tgz

4. Отредактируем файл shadow

 
 
  1. vi /tmp/state/etc/shadow

уберем из первой строки длинный хеш пароля, идущий после «root:», чтобы строка приняла вид

 
 
  1. root::13358:0:99999:7:::

Таким образом пароль для рута будет не установлен. Сохраним файл.

5. Теперь остается запаковать все обратно в архивы и положить на место

 
 
  1. cd /tmp/state
  2. tar -czf local.tgz etc
  3. tar -czf state.tgz local.tgz
  4. mv state.tgz /mnt/sda5/

6. Отмонтируем раздел ESXi и перезагружаемся

 
 
  1. umount /mnt/sda5
  2. reboot

После перезагрузки можно будет зайти в ESXi без пароля и установить его в настройках.

 

Небольшая демонстрация.

mergerfs: прозрачное объединение дисков (файловых систем)

The Perfect Media Server 2016Сегодня хочу рассказать о достаточно нетипичном решении для объединения дисков в один массив. Начну с юзкейса.

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

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

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

Работает оно ровно так — вы монтируете ваши диски по отдельности, а потом при помощи утилиты mergerfs объединяете их в виртуальную фс.

 
 
  1. mergerfs -o defaults,allow_other,use_ino,category.create=mfs,moveonenospc=true,minfreespace=1M  /tmp/backups/vol1:/tmp/backups/vol2 /backup

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

 
 
  1. df -h | egrep "Filesystem|backup"
 
 
  1. Filesystem                                      Size  Used Avail Use% Mounted on
  2. /dev/mapper/backup-backup                       3.6T  2.6T  858G  76% /tmp/backups/vol1
  3. /dev/mapper/backup2-backup                      916G   12G  858G   2% /tmp/backups/vol2
  4. vol1:vol2                                       4.5T  2.6T  1.7T  61% /backup
 
 
  1. ls /tmp/backups/vol1/Public/Video/Movies/Qatsi_Trilogy/
 
 
  1. '1. Koyaanisqatsi (1982) 1080p.mkv'
 
 
  1. ls /tmp/backups/vol2/Public/Video/Movies/Qatsi_Trilogy/
 
 
  1. '2. Powaqqatsi (1988) 1080p.mkv'
 
 
  1. ls /backup/Public/Video/Movies/Qatsi_Trilogy/
 
 
  1. '1. Koyaanisqatsi (1982) 1080p.mkv' '2. Powaqqatsi (1988) 1080p.mkv'

Как можно видеть: на одном смонтированном томе виден один файл, на втором — второй, а в точке монтирования mergerfs — оба.

Схема из man mergerfs:

 
 
  1.               A                B        =       C
  2.               /disk1           /disk2           /merged
  3.               |                |                |
  4.                -- /dir1         -- /dir1         -- /dir1
  5.               |   |            |   |            |   |
  6.               |    -- file1    |    -- file2    |    -- file1
  7.               |                |    -- file3    |    -- file2
  8.                -- /dir2        |                |    -- file3
  9.               |   |             -- /dir3        |
  10.               |    -- file4        |             -- /dir2
  11.               |                      -- file5   |   |
  12.                -- file6                         |    -- file4
  13.                                                 |
  14.                                                  -- /dir3
  15.                                                 |   |
  16.                                                 |    -- file5
  17.                                                 |
  18.                                                  -- file6

Конечно, нельзя рекомендовать это решение там, где вы имеете надежное оборудование и вам важна скорость — mergerfs работает через fuse, так что в любом случае это компромисс и не замена RAID0. Но в случае подобном моем — это однозначно лучший вариант, который можно придумать.

PS: К слову, mergerfs не единственная виртуальная ФС такого типа. Изначально я наткнутся на mhddfs, которая даже есть в репозитории debian. Однако, как я понял, ее разработка завяла, а вот тут пишут, что в ней есть баги и лучше таки использовать mergerfs.

Borg Backup: Cache is newer than repository.

Ошибка:
«Cache is newer than repository — do you have multiple, independently updated repos with same ID?»
может возникнуть, если репозиторий был восстановлен из бэкапа.

Лечится выполнением команды (на стороне клиента)

 
 
  1. rm -rf ~/.cache/borg/
  2. mv ~/.config/borg/security{,_bak}

Голос царя Александра III (нет, но все еще интересно)

В интернете наткнулся на такую запись:

Описание гласит:

В этом ролике слышный голоса царя Александра III и его жены Марии Фёдоровны (в начале)
В 1889 году во Фреденсборг, в резиденции датского короля была сделана звукозапись

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

Результаты фактчекинга таковы: на самом деле запись подлинная, из коллекции Готфрида Рубена — датского генконсула, который привез в Данию фонограф Эдисона и занимался продвижением этого агрегата в Скандинавии. Об этом написано на сайте государственной библиотеки Дании, и там же находится запись №127: Privatoptagelse med russisk-dansk ægtepar (Частная запись с русско-датской парой). Никаких упоминаний королевских кровей, но тем не менее кажется чем-то невероятным — услышать голос, датированный 1889-93 годами.

— «Я очень рада вас видеть сегодня. Потому, что хорошая погода, можно пойти гулять»
— речь на Датском
— «Вы хотите чтобы я говорил что-нибудь вам. Это не всегда так легко когда вы это… И еще вы прибавили, что хотите чтобы я спел что-нибудь. Ну что же вот как например это…»
— Поёт:
«Сам Бисмарк чуть от радости
Не вырвал клок волос,
Как телеграф известие
Такое нам принес,
Что немцы храбро заняли
Пункт важный и большой
И утверждали в Африке
Права страны родной…
С тех пор в Берлине стар и млад
Одно лишь и твердят:
Nach Afrika, Nach Kamerun…
Так немцы говорят!»
-«…Если вы заранее меня предупредили, так это другое дело. Я бы взял с собой книгу или что-нибудь в этом роде, чтобы мне прочитать. А так прямо из головы это нелегко. Вы меня застали врасплох. И конец. До свидания, господа.»
— речь на Датском

HOW-TO по миграции файловых серверов

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

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

Итак, первым делом на целевом сервере я создаю папку work, например на диске E:, и расшариваю ее под именем «workE$». Права доступа: полный доступ для SYSTEM, OLDDOMAIN\Domain Admins, NEWDOMAIN\Domain Admins — это позволит копировать конкретные расшареные папки со старого сервера по сети внутрь work с сохранением исходных прав доступа.

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

Далее, на исходный сервер устанавливается утилита robocopy и изготавливается вот такой скрипт:

rcopy.cmd
 
  1. chcp 1251
  2. robocopy "d:\MyShare" "\\fs-new.local\worke$\MyShare" /MIR /SEC /NS /NC /NDL /R:1 /W:1  /UNILOG:"\\fs-new.local\worke$\MyShare.txt" /TEE
  3. pause

(первая строка нужна на случай, если исходная папка называется по-русски — без этого у меня ломалась кодировка и все файлы копировались с кракозябрами. )

Запускаете cmd с повышенными правами и стартуете скрипт. Он полностью копирует исходную папку на целевой сервер. Что важно — робокопи с этими ключами делает копию директории, а при повторном запуске — актуализирует ее (обновляет измененные файлы, добавляет новые, удаляет те которые были удалены из исходной папки). Поэтому даже если исходная шара была очень большой и копировалась несколько суток, то путем второго-третьего запуска можно уже довольно быстро актуализировать состояние на целевом сервере и пользователи не потеряют те изменения, которые были сделаны во время копирования.
Отдельно замечу что robocopy пишет в лог все ошибки копирования (строго говоря при первом запуске в лог улетают все копируемые файлы, так что лог может быть большим, но при повторном запуске туда попадают только изменения и ошибки, что довольно удобно — как раз видно, например, что на какую-то папку нет прав доступа)

Я так и делаю. Во время копирования или актуализации, пока выполняется скрипт, уже можно на целевом сервере расшарить папку и назначить права доступа к шаре, если они были настроены каким-то специфическим образом. Как только файлы актуализированы (обычно, конечно, актуализацию приходится проводить в нерабочее время) — на старом сервере шара отключается, и поднимается с тем же именем, правами только на чтение, и с двумя файликами: текстовым файлом с содержанием «уважаемые пользователи, файловые ресурс смигрирован на новый адрес: \\новый\адрес, пожалуйста запомните его или скопируйте себе ярлык»,  и ярлыком на новое место, то есть на шару на целевом сервере. Таким образом пользователи, заходя по старому адресу, обнаруживают что ничего не работает, но у них есть подсказка. Из своего опыта могу сказать что даже если у пользователей есть ярлыки куда-то вглубь, то все равно так или иначе они добираются до корня старой шары с подсказкой и вопросов возникает минимум, так что этот метод вполне стрессоустойчив для администратора =)

В моем случае я дополнительно собираю целевые шары на сервере DFS (рекомендую прочитать отдельный пост на тему настройки DFS: Перенастройка DFS для использования DNS-резолвинга), постольку поскольку целевых серверов в моем случае много и хочется дать пользователям единую точку входа. Комментарием тут может быть разве что рекомендация скрывать шару на целевом сервере, то есть реализовывать такую схему:

исходный сервер: \\old-srv\myshare
целевой сервер: \\new-srv\myshare$
dfs-сервер: \\dfs\rootname\myshare

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

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

Укол спутником

В прошедшую пятницу сходил привился спутником V (он же Гам-Ковид-Вак). Не скажу, что невероятно доверяю отечественным вакцинам, произведенным в спешке и с целью в очередной раз продемонстрировать всему миру россию вперде, однако какое-то время с начала вакцинации уже прошло — массовых смертей от вакцины нет. При таком раскладе ждать остается непонятно чего — то ли другой вакцины (а не будет ли там того же набора вопросов, тем более что пфайзер до нас доберется нескоро, а на горизонтах только другие отечественные же аналоги), то ли вообще коллективного иммунитета без попыток прокачать свой личный. Так как пока что я продолжаю сидеть на удаленке, тем временем как вероятность словить ковид в городе все еще растет, я решил что во-первых стоит в относительно безопасных домашних условиях получить иммунитет, а во-вторых — стоит с этим поспешить, пока, собственно, есть возможность сидеть дома.

Так что записался через приложение ЕМИАС и сходил. Так что там и как? Ну, пришел в поликлинику, получил стандартную анкету про «здоров как бык» и соглашение что приперся добровольно.

Не понимаю, на самом деле, что мешало выложить эту анкету в инет и дать возможность ее заполнить заранее. С другой стороны не так много времени на это и нужно, так что в целом ладно…

Забавно, что, хотя сейчас в Москве вакцинация официально доступна для ограниченного числа лиц (сегодня, в день этого поста список выглядит так) — никто ни в процессе записи, ни в поликлинике, не спросил никаких справок на этот счет (хотя при записи через московский портал было предупреждение о необходимости справки с работы).

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

Основная причина возникшего скопления людей — один единственный кабинет, в котором вакцину, собственно, кололи. При этом работало фактически 4 кабинета: в два из них запускали людей, заполнивших анкету — забирали ее, меряли температуру, забивали какие-то данные в компьютер и сразу записывали на второй прием (вакцина двухкомпонентная и вторая доза должна быть вколота через 3 недели); после ты попадал в кабинет вакцинации, и шел к последнему — ожидать получения памятки и документа о сделанной прививке.

Так вот, показательным является то, что в первый кабинет я вошел почти точно во время своей записи (может быть минут на 10 позже), а потом более полутора часов ждал когда же меня уколят. Местные врачи объясняли что вакцина выгружается из морозильника (а хранится она в замороженном состоянии) по 5 доз, так что ожидающие люди делятся на пятерки… но на самом деле непонятно почему это должно так тормозить процесс — ведь люди вот они тут, и даже если вакцина размораживается порционно, то почему бы ее не размораживать заранее и не по 5 а по 10 доз, не доставать очередную пятерку когда из прошлой уже двое-трое привиты и отпущены? Короче это какой-то организационный фейл, потому что чистого времени на все про все уходит минут 10 от силы, а я проторчал в поликлинике 2 часа. Это при том что всё по записи и записавшихся но не пришедших людей там оказалось человека 2 из пары-тройки десятков.

Интересно еще отметить, что всем было сказано после прививки посидеть полчасика тут же — пока готовятся документы и вообще — на случай непредвиденной реакции организма. Интересно, часто ли такое случается? В любом случае спасибо за предупреждение )

Ну и коротко об ощущениях после прививки. Первые 12 часов вообще ничего такого, разве что появилось легкое недомогание, хотя может больше усталость сказалась. А вот через 24 часа накрыло как хорошим орви. Не грипп, не смерть и ужас, но кости ломит, хвост отваливается, температура по ощущениям около 38. Об этом, кстати, предупредили и сказали температуру за 38 (если такая будет) сбивать жаропонижающими, и пить что-то против аллергии, опять же если будет какая-то аллергическая реакция. Но я в итоге ничего не пил, хорошо отоспался, пропотел и на вторые сутки уже чувствую себя человеком поправляющимся. Все еще сильная слабость, место укола на руке болит словно по нему хорошо ударили (но без синяков и каких-то внешних проявлений вообще), чувствуется невысокая температура. В общем типичное орви (но без насморка, кашля и прочих внешних проявлений орви самого по себе), которое перешагнуло свою самую неприятную стадию =)

Личный опыт вакцинации пока могу признать успешным — жив-цел, почти орёл =)

ЗЫ: мой личный опыт может отличается от любого другого, на вакцинацию я шел по своим, изложенным в начале, соображениям и никого ни к чему не призываю — своя голова ближе к телу).

Заполнение mp3-тегов скриптом

Довелось скачать саундтрек к игре в виде кучи файлов без тегов вообще.

Захотелось на скорую руку заполнить хотя бы названия и номера треков (альбом/год/жанр — одинаковые для всех, с этим все сильно проще).

Для начала из имени каждого файла нужно вычленить название трека. Используем sed в однострочном цикле для разделения имени файла на три блока. Блоки в sed выделяются экранированными скобками: начало — \(, конец — \)

 
 
  1.                                                        вычленяем блок №2
  2.                                                         |             |
 
 
  1. for file in *.mp3; do name=$(sed "s/\(^.*_.\{1,3\}_\)\(.*\)\(\.mp3\)/\2/" <<< $file); echo $name ; done;
 
 
  1.                                           |                     |    
  2.            блок №1: начало строки, любые символы,          блок №3: .mp3
  3.                     подчеркивание, 1-3 любых символа,
  4.                     подчеркивание

Вывод:

 
 
  1. chat_thiscouldbeAWESOME
  2. lab sewers
  3. chat_downthe
  4. ...

(да, если вы решаете проблему с помощью регулярных выражений — у вас уже 2 проблемы, но в данном случае это отличное решение).

Убедившись что имена получаются корректные, меняем echo $name на редактор тегов mid3v2

 
 
  1. for file in *.mp3; do name=$(sed "s/\(^.*_.\{1,3\}_\)\(.*\)\(\.mp3\)/\2/" <<< $file); mid3v2 -t "$name" "$file" ; done;

Самое сложное сделано. Теперь номера треков (всего их 46, так что это число я подставляю вручную):

 
 
  1. i=1; for file in *.mp3; do mid3v2 -T  "${i}/46" "$file" ; ((i+=1)); done;

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

 
 
  1. for file in *.mp3; do mid3v2 -y 2010  "$file" ; done;

PS: утилита mid3v2 (рекомендуется как полностью поддерживающая v2/utf8-теги) входит в питоновский пакет mutagen и ставится примерно так (для debian/ubuntu)

 
 
  1. apt install python3-mutagen

или так (установка в пользовательский профиль из репозитория pypi)

 
 
  1. pip3 install --user mutagen

Осенние белочки

Debian 10 Buster + openbox (установка и настройка)

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

Читать: Debian 10 Buster + openbox (установка и настройка)