Официальная возможность получить лицензионный софт бесплатно.
Giveaway of the Day
Это не реклама!

Щелкните для получения прогноза по Биробиджану


среда, 13 декабря 2017 г.

bash: массовое уменьшение фото в каталоге

Есть в нашем мире долбодятлы. Чем они отличаются от обычных людей? Например тем, что принципиально не способны выбирать для работы правильный инструмент. Например, они пробивают перфоратором с метровым буром деревянную доску-десятку. Или забивают в нее гвозди кувалдой, которой только что вгоняли костыли в шпалы. Или будут есть китайскими палочками не только лапшу и салаты, но и яичницу-глазунью или суп. Только потому, что ухватив инструмент, они не хотят брать другой. Или не знают, что он есть. Но чаще им просто лень потратить несколько секунд для того чтобы взять более подходящий инструмент.
Как известно, каждый дрочит как хочет, и я не собираюсь обсуждать любителей забивать гвозди микроскопом. До тех пор, пока это не мешает работе моих файловых серверов. Нет, ни любители палочек, ни любители перфораторов мне не мешают. А вот любители размещать на серверах фото в огромном разрешении - эти мешают. И они тоже относятся к породе долбодятлов.
Например, важный снимок - ход строительства одного из наших объектов. Снято на мультимегапиксельную говномыльницу. Размер снимка 5 мегов. Сюжет: кусок кирпичной стены и тропинка вдоль нее. Всё. Никаких мелких или существенных деталей нет. Просто оператору было лень выбрать режим съемки 3 или 2Мпикс, он как выставил при покупке 12Мпикс, так и щелкает всё подряд.
Возникает вопрос: как утоптать всё это в более-менее скромный объем, если пациент принципиально не желает пользоваться настройками своего фотоаппарата или программой для уменьшения геометрических размеров фото? Очень просто: уменьшить эти снимки самостоятельно. В этом нам поможет convert из пакета ImageMagick.

Находим каталог с большим количеством неоправданно жирных фото.

find -iname *.jpg -size +3M -exec ls -l "{}" \; >large-photos

Просматриваем этот файл. Я делаю это вручную, но только потому что, мне лень еще полнее автоматизировать процесс, но может когда-то и доведу его до полного солипсизма полного автоматизма. Находим каталог-жертву и делаем ему матумбу (записано в одну строку, но внутри скрипта можно размазать и на несколько:

for a in *;do fn="${a%.*}";fe="${a##*.}";convert $a -resize 50% ${fn}s\.$fe;chmod ${fn}s\.$fe --reference=$a;chown ${fn}s\.$fe --reference=$a;touch ${fn}s\.$fe --reference=$a;done

Итак, по порядку:

for a in * - список файлов текущего каталога
fn - имя файла без расширения, выделяется с помощью штатных возможностей bash. (в Advanced Bash Scriptuing Guide глава 10. Manipulating Variables, раздел 10.1. Manipulating Strings, подраздел Substring Removal)
fe - расширение файла без имени, выделяется аналогично fn. Две этих раздельных части имени пригодятся позже
convert ИМЯ_ИСХОДНОГО_ФАЙЛА -resize 50% - уменьшает геометрический размер изображения в 4 раза (на 50% по каждой стороне).
${fn}s\.$fe - ...и записывает его файл с именем вида fns.fne, где "s" - это дописываемый к исходному имени суффикс, сокращение от слова "scaled" (масштабированный). Чтобы не возиться с определением места, куда вставить эту "s", я и использую отдельно взятые имя и расширение. На всякий случай экранируем точку, отделяющую имя от расширения.
chmod, chown и touch - заметаем следы, назначая свежесозданному мини-рисунку все атрибуты его большего предка: владельца, группу, права доступа и времена. У всех трёх команд набор параметров одинаковый: имя файла, которым манипулируем и после ключа --reference - имя файла, у которого берем "эталонные" значения. В моем случае это исходный файл.

Например, есть файл DSC01234.jPg. Соответственно:
fn=DSC01234
fe=jPg
уменьшенная копия будет записана в файл DSC01234s.jPg, и получит все атрибуты оригинала.

Я ориентировался на имена файлов, создаваемых нормальными камерами, то есть, не содержащие пробелов и спецсимволов. Возможно, для большей универсальности понадобятся кавычки.
Почему $fe используется сама по себе, а $fn - только в форме ${fn}? Потому что после $fn идет суффикс "s", который в противном случае будет считаться частью имени несуществующей переменной $fns.
Разумеется, для красоты можно ${fn}s\.$fe запихать в переменную, и, возможно, так и придется сделать при обработке файлов с вычурными именами, но пока для меня это не актуально.

четверг, 17 августа 2017 г.

Adtool и встроенная убунта в win10

В феврале 2017 я коротко рассказал о найденных мной утилитах для работы с AD и WMI из линукса.
Там же есть вполне реальный пример, где я ищу владельцев компьютеров. С тех пор прошло около полугода, мой боевой потрёпанный винсервер-2003 (на рабочем месте) заставили сменить на win10. Не скажу, что оно меня сильно радует, но после апгрейда до 1703 интерфейс выглядит достаточно удобным (я сказал "достаточно удобным", а не просто "удобным" - это значит, что в нем уже можно работать, матерясь не через каждую минуту, а не чаще чем раз в полчаса-час), и появилась отличная штука - "Подсистема Linux для Windows":

sergei@cnt300022:~/bin$ uname -a
Linux cnt300022 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux

sergei@cnt300022:~/bin$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:        16.04
Codename:       xenial

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


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

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

#!/bin/bash
# Выгребаем из AD имена компов и находим их владельцев

# Для элегантности используем переменные и константы вместо длинных выражений.
COMPS_FILE=/tmp/comps-list.txt
OUT_COMPS_FILE=/tmp/comps_out.csv

# В моем домене все компы имеют вид cnt30xxxx, где cnt30 - постоянная часть, а

# xxx ::= [0-9]{3}[0-9a-z]{1} для рабочих станций и typ[0-9]{3} для других типов железа
# Однако, разные типы компов могут жить в разных OU, поэтому вместо "list" использую "search"

# Для удобства дальнейшей обработки найденное приводим к верхнему регистру
adtool search name cnt30*|grep -iE ^cn=cnt30[0-9]{3}[0-9a-z],|tr [:lower:] [:upper:]|sort>$COMPS_FILE


# Поскольку вывожу я всё это в подобие CSV, то сначала пишем строку заголовка
echo \"Comp DN\"\;\"Comp CN
\"\;\"UAC\"\;\"Managed by\"\;\"Description\">$OUT_COMPS_FILE

# А дальше стандартный скучный цикл построчного чтения из созданного чуть выше списка
while read COMP_NAME; do

# Поскольку attributeget работает по CN, а не по DN, но при этом search возвращает именно DN,

# то надо из DN как-то выделить CN. 
# Так можно и работает - так же я делал и в феврале, выкусывая слева "cn=", а справа всё
# после первой запятой
#    PURE_NAME=$(echo ${COMP_NAME/CN\=/}|sed "s/\,.*//")
# Но можно и так (берем 9 знаков, начиная с третьего, нумерация с нуля):
# cn=cnt300000
# 0123456789AB
    PURE_NAME=${COMP_NAME:3:9}

# Не уверен, может ли attributeget получать сразу несколько атрибутов, вероятно - нет,

# так что работаем по старинке: 1 переменная хранит 1 атрибут
    COMP_DESC=$(adtool attributeget $PURE_NAME description)

# Здесь тоже надо выделить чистое CN из прочитанного DN, но имя пользователя имеет неизвестную
# длину, поэтому выбираем его универсальным, хотя и более медленным способом
    COMP_MGBY=$(adtool attributeget $PURE_NAME managedby|sed "s/CN=//;s/\,.*//")

# Меня не очень волнует, есть ли атрибут managedBy у заблокированных компов, но раз в списке
# будут они все, то добавим столбец, показывающий состояние учётки.
# За признак enabled/disabled отвечает бит со значением 0b10 или 0d2, сделаем с ним AND
# и точно будем знать: если 0, значит учетка активна, если 2 - заблокирована
    COMP_UAC=$(( $(adtool attributeget $PURE_NAME UserAccountControl) & 2 ))

# Осталось только всё это красиво вывести
    echo \"$COMP_NAME\"\;\"$PURE_NAME\"\;\"$COMP_UAC\"\;\"$COMP_MGBY\"\;\"$COMP_DESC\"
done <$COMPS_FILE >>$OUT_COMPS_FILE

exit

Во время работы скрипта будут, скорее всего, появляться сообщения типа "error: Error in ldap_get_values for ad_get_attribute:no values found for attribute managedby in object CN=CNT306552,OU=330,OU=Comps,OU=Domain Root Entry,DC=CONTOSO,DC=MS,DC=ru", это нормально - они выводятся на stderr, а наш вывод через stdout падает сразу в файл, так что чистить выходной файл от мусора не понадобится.

На выходе получим вполне приятный CSV вроде:

"Comp DN";"CompCN";"UAC";"Managed by";"Description"
...
"CN=CNT30002A,OU=330,OU=COMPS,OU=DOMAIN ROOT ENTRY,DC=CONTOSO,DC=MS,DC=RU";"CNT30002A";"2";"Сергей Павлович";"убитый комп"
"CN=CNT30002B,OU=330,OU=COMPS,OU=DOMAIN ROOT ENTRY,DC=CONTOSO,DC=MS,DC=RU";"CNT30002B";"0";"Сергей Павлович";"тестовая Win10"

среда, 16 августа 2017 г.

Неожиданное продолжение темы с bluetooth на Lenovo B590

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

В этот раз решение нашлось здесь. В логах упорно появлялось довольно странное сообщение:

Direct firmware load for brcm/BCM.hcd failed with error -2

Иногда там фигурировало и слово patch. У меня сразу появилась мысль попробовать переименовать /lib/firmware/brcm/BCM43142A0_001.001.011.0161.0172.hcd в просто BCM.hcd. Полистав сообщения на форуме (ссылка выше), я понял, что недалёк от истины - народ советовал сделать то же самое. Плюс рекомендовали не просто перегрузить комп, а именно через выключение питания, т.с. "холодный старт".

Помогло - блютус заработал.

пятница, 26 мая 2017 г.

SQUID, AWK и статистика

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

Что нужно? Нужно посчитать, сколько всего трафика за сутки израсходовал тот или иной пользователь.

Решаем задачу наличными силами и подручными средствами. Лог сквида имеет вполне определенный формат, гугл в помощь. Мне нужны поля: передано байт (5), имя пользователя (8) и результат запроса (4). Ну и воспользуемся такой прелестью авка, как ассоциативные массивы. Дальше - просто копипаста рабочего скрипта.
MAWK давно не обновлялся, поэтому я явно указал интерпретатор GAWK.

#!/usr/bin/gawk -f
# usage:
# 1) get_sqlog.awk filename
# 2) cat filename|get_sqlog.awk

# Если нет пользователя или есть один из двух отлупов, то переходим к следующей строке
{if ($8 == "-" || $4 == "TCP_DENIED/407" || $4 == "TCP_DENIED/403") { next }
# Ассоциативные массивы, в качестве индекса - имя пользователя
# Сколько раз он нам попался
    ++occurrences[$8]
# Его трафик
    summary[$8]=summary[$8]+$5
}
END {
# Проходим по всем элементам массива и красиво печатаем их
# Переменная а принимает значения индексов, определенные во время анализа
for (a in occurences){
    printf "%-30s:%10d:%10d\n",a,occurrences[a],summary[a]
    }
}

Под катом подробное описание.

среда, 24 мая 2017 г.

SQUID: вывод лога в человеческом виде

Ищу нормальный анализатор лога, который не будет рисовать красивые html-картинки, а просто тупо подобьет бабки и выдаст статистику за нужный период в разрезе пользователей.

Не нашел. Пока изучаю побочные действия и буду рисовать сам. Когда-то я уже приводил чью-то идею о преобразовании даты в логе в человеческий вид. Довольно известная "шутка" на Perl.

Но awk мне как-то милее.

awk '{ print strftime("%Y-%m-%d %H:%M:%S",$1)","$2","$5","$8}' имя_логфайла

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

Да, работает это только с gawk. А mawk почему-то заявляет, что у него нет функции strftime.

вторник, 2 мая 2017 г.

MS DOS: Обращение к счетчику цикла изнутри самого цикла

Как ни крути, а cmd.exe и command.com - это останки MS DOS, поэтому я так и озаглавил эту запись.

Итак, server 2008, cmd.exe, батник, цикл... Что я хочу сделать? Я хочу вывести числа от 1 до 20, причем числа меньше 10 должны выводиться с ведущими нулями. Способов для этого много, но все они упираются в присвоение какой-то переменной текущего значения счетчика цикла.
Чтобы не мудрить с проверками, я решил использовать наиболее универсальный способ: прибавляю к числу 100 и из полученного значения беру 2 правых символа. Можно прибавлять что угодно, главное, чтобы справа было нужное число нулей, чтобы не исказить само значение.

for /L %%a in (1,1,20) do (
  set /A b=100+%%a
  set b=%b:~-2%
  echo a=[%%a] b=[%b%]
)

По идее у меня должно напечататься 20 строк вида:

a=[x] b=[zy]

где x - значение переменной счетчика цикла, y=x, а z - ведущий ноль, если он есть.

Однако, вместо этого печатаются строчки вида:

a=[x] b=[]

Я перепробовал все варианты, какие только смог придумать. Увы, все команды работают с %%a нормально, кроме команды присвоения. Вариант с setlocal EnableDelayedExpansion тоже не помог. Пришлось выкручиваться. Частично решение, саму идею, нашел здесь.


for /L %%a in (1,1,20) do (
  call :MySub %%a
  echo a=[%%a] b=[%b%]

)

exit /b 0

:MySub
  set /A b=100+%~1
  set b=%b:~-2%

exit /b 0


После этого всё заработало.

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

вторник, 4 апреля 2017 г.

Auf viderseen, Гримм

И снова подошел к концу очередной сериал, от которого было невозможно оторваться. Пять с половиной лет я следил за приключениями Ника Бёркхарта и его спутников. Пока что это единственный после "Звездных врат" сериал, где мне не хотелось за серии ставить​ оценки ниже чем 9 из 10. И я сомневаюсь, что в ближайшее время найдется что-то подобное по качеству. "Нация Z" хороша, но это совсем другой жанр, комедия с претензией на глубину. А "Гримма" я даже и не знаю, как охарактеризовать. Странная, но чертовски захватывающая смесь сказки, фентези и не самого плохого детектива.
Те, кто ждал, что Ник в конце всех оживит, оказались правы, но такого варианта концовки не предвидел никто из комментаторов.
Если рассуждать в терминах той вселенной, то теперь создан практически нерушимый союз гримма, ведьмы, существ и колдуна. Недаром же Диана упомянула, что тройняшки тоже идут с ними убивать каких-то тварей, да еще и в компании папы с мамой. Одно непонятно, какого из двух пап имела в виду Диана - биологического или официального? Впрочем, если на "дело" пойдут оба, то, как в той песне, любому чудищу смерть.
Жаль, что сериал закончен, но концовкой авторы, отрубившие множество сюжетных линий, постарались не оставить чувство незавершенного, как это было с "LOST". В самом деле, зачем пытаться размотать все истории - монет или королевской семьи - за несколько лет жизни только одного персонажа. Келли явно будет чем заняться, когда Ник выйдет на покой...
Надеюсь, что когда-нибудь снимут продолжение...

пятница, 10 марта 2017 г.

WinWord и вставка названия главы в колонтитул

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

Вот как это делается в Star/Open/Libre-office:

1. присвоить нужным заголовкам соответствующие стили
2. открыть колонтитул
3. Выберите команду Вставка – Поля – Дополнительно и перейдите на вкладку Документ.
NB! в вики по ссылке в русской версии ошибка - надо открывать вкладку "Документ", как на моем скриншоте, а не "Функции", как написано там. В английской версии той же вики всё правильно.
4. В списке Тип выберите пункт "Глава", а в списке Формат – пункт "Название и номер главы".
5. Нажмите кнопку Вставить, затем кнопку Закрыть.

Скриншот из Apache OpenOffice 4.1.3 под XUbuntu 16.04.2

А вот через какую жопу это делается в излишне популярном продукте.

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

На самом же деле всё намного проще, и вместе с тем сложнее.

1. Вставка - Поле
2. Категория: Связи и ссылки
3. Поле: StyleRef

Скриншот из MSO 2003 под W2K3/server, тема "классическая"

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

пятница, 17 февраля 2017 г.

Ubuntu: ADTool и WMIC

Когда-то обе эти утилиты были в репозиториях убунты, но по какой-то причине их оттуда убрали. А зря.

ADTool

ADTool не имеет никакого отношения к рекламе (advertising), зато имеет конкретное отношение к активному каталогу (Active Directory).
По сути, это оболочка над клиентом OpenLDAP, позволяющая максимально комфортно обращаться к ADDS из-под линукса. Распространяется в исходниках, работает нормально.

https://gp2x.org/adtool/

В комплекте идет довольно короткий но понятный ман: https://gp2x.org/adtool/usage.html. Из-за ограниченных прав в домене, я больше всего использую команды search (поиск объектов по значению атрибута) и list (просмотр содержимого контейнера), которых как раз недостает в самбовской net.

Базовые параметры - имя пользователя, пароль, узел, от которого начинается поиск, имя сервера AD - можно задавать каждый раз в командной строке или один раз в файле конфигурации.

среда, 8 февраля 2017 г.

bash, AD: выбор пользователей из группы, входящих и в другую группу

Есть в нашем домене группа, куда добавлены работники разных филиалов, но мне надо обработать только тех, что находятся в моем филиале. Причем не всех, а только из отдельных подразделений.
В свое время я предлагал сделать возможность создания вложенных OU, чтобы группировать пользователей по отделам внутри филиала. В ответ узнал очень много о своей умственной неполноценности.
Не буду сейчас характеризовать тех, кто этого добивался - свалить всех в одну кучу, потому что свои проблемы я решил. Не так эффективно, как можно было, но для моих целей достаточно. А как они там фигачат километровые скрипты на PowerShell, чтобы найти жемчужинку в тоннах информационного навоза, меня не касается.
Однако, изменить структуру домена я не могу, поэтому приспосабливаемся.

Итак, задача:
1. есть группа, в которую свалены работники разных филиалов. Все логины имеют вид фамилия_инициалыN, где N - цифра, добавляемая в случае совпадения фамилии и инициалов (вонючий костыль вместо того, чтобы разрешить создавать субдомены)
2. мне надо отобрать своих
3. что-то с этими своими сделать.

bash: суммирование столбца чисел

Один из возможных вариантов. Есть и другие, например, преобразовать столбец в строку и скормить ее bc или dc.


Суммируем 3-й столбец из лог файла.
https://www.opennet.ru/tips/457_file_awk_log_print.shtml

cat logfile| awk '{s += $3} END {print s}'

То же самое, но более развёрнуто и с пояснениями:

http://kb.h1host.ru/article/view?id=55
 

пятница, 3 февраля 2017 г.

Хранение сообщений в Zimbra: доведение до нервного срыва

Накопились в хранилище зимбры несколько десятков гигов старых сообщений, которые почему-то не прибились при автоматической чистке почтовых ящиков.
Меня смутил их размер - самих файлов с сообщениями, поэтому решил посмотреть в общих чертах, что там внутри. Через штатный просмотрщик MC сообщения показываются нормально, но он не умеет парсить структуру SMTP, поэтому я такие сообщения скопировал в свой сетевой каталог, дабы глянуть их через Thunderbird.
Копировал с помощью rsync. Сразу удивило, что, несмотря на использование опции -z, ускорения передачи не было, словно копировались уже сжатые данные. Ну да ладно, это не критично.
Захожу в FAR-e из-под винды в этот каталог, открываю первый попавшийся файл и выпадаю в осадок: внутри просто мусор. Открываю этот же файл через MC на сервере, куда его скопировал - MC показывает нормальные внутренности письма.
Копирую файл на свой локальный диск - внутри мусор. Копирую этот "мусор" обратно на самбу - MC показывает всё как положено.
Уже начал подозревать, что умудрился каким-то непонятным образом поймать вирус-шифровальщик, причем очень хитрый, который шифрует файл не на диске, а при открытии, в реальном времени. На всякий случай тот же самый файл из того же самого каталога попробовал открыть на другой машине с другой ОС и другим пользователем. Мусор.