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

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


четверг, 28 апреля 2016 г.

Массовое переименование файлов в bash с заменой символов в середине имени

Притомили коллеги, лепящие в именах файлов все символы, предусмотренные юникодом. Кое-кто даже умудрился (честно, я не знаю, как) сохранить файл, в имени которого несколько штук \127!

Но это уже клинический случай, а есть более мягкие, когда по неизвестной мне причине в именах появляются точки с запятой. Для устранения этого безобразия заменим ";" на ",":

find -iname *\;*|while IFS='' read line; \
  do NEWNAME=`echo "$line"|sed 's/\;/\,/g'`; \
  mv "$line" "$NEWNAME"; done

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

понедельник, 25 апреля 2016 г.

Netsarang XShell: No matching outgoing encryption algorithm found

Пользуюсь этой штукой, частью пакета Netsarang XManager в качестве универсального терминального клиента - ssh, telnet, *modem и т.д.

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



среда, 20 апреля 2016 г.

Сетевое сканирование на Windows Server 2003

Понадобилось перекинуть каталог для результатов с самбы на 2003 сервер. Ну вот понадобилось, и всё.
И по ряду причин сервер назначения, прописанный в 50+ МФУ менять проблематично. Но это фигня - МФУ и до этого работали с псевдонимом:

1. был сервер srv012
2. он умер и его обязанности легли на srv042, который в DNS получил псевдоним srv012
3. все МФУ радостно сканировали на 042, уверенные, что сканируют на 012
4. после переназначения псевдонима 012 на сервер srv047 почти все МФУ сканировать отказались, причем сканирование на "настоящий" 047 идет "на ура".

Выяснилось, что до 2008, винда не очень любит, когда к ней обращаются не по имени-отчеству, а по прозвищу (не путать с украинским прiзвищем-фамилией). Лекарство описано здесь.
(pluto в примере - сервер 2003 или ему подобный)

===
  • connected to server Pluto with the credentials of a user with administrative rights on the server;
  • start Registry Editor (Regedt32.exe);
  • locate and click the following key in the registry: HKEY_LOCAL_MACHINE\System
    \CurrentControlSet\Services\LanmanServer\Parameters
  • on the Edit menu, click Add Value, and then add the following registry value:
    Value name: DisableStrictNameChecking
    Data type: REG_DWORD
    Radix: Decimal
    Value: 1
  • quit Registry Editor;
  • restart the server Pluto.

===

понедельник, 18 апреля 2016 г.

Zimbra, Outlook и ошибка 0x800ccc0f

Ситуация:Outlook 2010 в качестве POP3-клиента
Zimbra Release 8.0.6.GA.5922.UBUNTU12.64 UBUNTU12_64 FOSS edition

Учетная запись настроена так, чтобы удалять с сервера сообщения старше 2 недель. В основном всё проходит нормально, если проверять почту хотя бы раз в неделю. Но вылезла достаточно давно странная штука: если старых писем больше какого-то предела (не всего писем в инбоксе, а именно старых, подлежащих удалению), то аутлук затыкается на этапе получения новой почты с ошибкой 0x800ccc0f "Почтовый сервер разорвал соединение".

Лечилось это ручным удалением старых писем через веб-интерфейс, но ситуация всё равно не нормальная.

Внимательное изучение mailbox.log показало такую вот картинку:

---
2016-04-18 08:40:58,029 INFO  [Pop3Server-696] [name=user@domain;ip=***;] pop - DELE elapsed=0
2016-04-18 08:40:58,030 WARN  [Pop3Server-696] [name=user@domain;ip=***;] pop - throttling POP3 connection for account оченьдли-нная-стро-кавс-стилеUUID*** due to too many requests
2016-04-18 08:40:58,030 INFO  [Pop3Server-696] [name=user@domain;ip=***;] pop - DELE elapsed=0
2016-04-18 08:40:58,081 INFO  [Pop3Server-696] [ip=***;] pop - connected
2016-04-18 08:40:58,082 WARN  [Pop3Server-696] [ip=***;] pop - throttling POP3 connection for remote IP ***
2016-04-18 08:40:58,082 INFO  [Pop3Server-696] [ip=***;] pop - CAPA elapsed=0
2016-04-18 08:40:58,085 INFO  [Pop3Server-696] [ip=***;] pop - connected
2016-04-18 08:40:58,086 WARN  [Pop3Server-696] [ip=***;] pop - throttling POP3 connection for remote IP ***
2016-04-18 08:40:58,086 INFO  [Pop3Server-696] [ip=***;] pop - CAPA elapsed=0
2016-04-18 08:40:58,089 INFO  [Pop3Server-696] [ip=***;] pop - connected
2016-04-18 08:40:58,089 WARN  [Pop3Server-696] [ip=***;] pop - throttling POP3 connection for remote IP ***
2016-04-18 08:40:58,089 INFO  [Pop3Server-696] [ip=***;] pop - CAPA elapsed=0

---
Причем, судя по логам аутлука и дампу трафика, снятого Wireshark, на разных клиентах это происходило после удаления 195 сообщения, то есть примерно на 200-ой команде после логина.

Судя по этому http://community.zimbra.com/collaboration/f/1886/t/1084347 некий троттлинг (а это чего?) беспокоит не меня одного. Похоже, что это количество запросов в единицу времени либо количество однотипных команд.

---
$ zmlocalconfig|grep throttle
imap_throttle_acct_limit = 250
imap_throttle_command_limit = 25
imap_throttle_fetch = true
imap_throttle_ip_limit = 250
lmtp_throttle_ip_limit = 0
pop3_throttle_acct_limit = 200
pop3_throttle_ip_limit = 200

---

То есть, количество POP3-команд с одного адреса или с одного аккаунта в секунду (?) не может превышать 200 штук. После увеличения лимитов

---
$ zmlocalconfig -e pop3_throttle_acct_limit=2000
$ zmlocalconfig -e pop3_throttle_ip_limit=2000

$ zmcontrol restart
---

 Стало полегче... Но почему же раньше не было таких затыков?

пятница, 8 апреля 2016 г.

OpenOffice и курсоры MySQL

Не очень разработчики ООО (да и LO) любят MySQL. Самое наглядное проявление этого - полное отсутствие поиска, не говоря уже о замене, в редакторе скриптов. Да-да, в редакторе запросов в принципе нет такой возможности. Уже смешно.
Про неумение LO работать с теми скриптами, с которыми OOO справляется влёт, я уже молчу.

Но выяснилась, причем совершенно в неподходящий момент, неожиданная бяка. Понадобилось использовать курсоры в хранимой процедуре, чтобы не плодить множество вложенных select-ов. Но, как это иногда бывает, MySQL server gone away из-за таймаута. (это в ООО, а LO модча показывал пустое окно вместо результатов запроса). Методом тыка было выяснено, что сервер "уходит" на команде open cursor.

Почему я решил, что виноват офис? Да потому что из-за неудобства IDE в этом офисе, для написания и отладки запросов я использую MySQL Workbench, и в ней всё работало отлично, сервер никуда не пропадал и результаты возвращались как положено.

Печально, но выяснилось, что использовать курсоры нельзя. Пришлось, благо, что хранимые процедуры/функции пишутся на более "стандартном" диалекте, близком к обычным ЯВУ, лепить циклы опроса и совершать прочие некрасивые действия, чтобы имитировать функциональность курсоров.

Суть задачи:

Есть система инвентаризации ИТ OCS-NG Inventory. Ее БД хранится в виде множества связанных таблиц, где основная таблица ocsweb.hardware, а большинство остальных таблиц связано с ней соотношением одно-ко-многим, то есть, для каждой записи в hardware может быть несколько записей в других таблицах.

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

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

Допустим, один монитор сообщил о себе всё, и group_concat может сделать примерно такое: "модель (производитель), sn: номер". Но в случае старого монитора такая красота превратится в уродливое "  (проихводитель), sn:  " или вообще в "  (  ), sn:  ", за что я уже получал (и справедливо) от начальства.

Стало быть, надо обработать возможные ситуации разной заполненности полей и в зависимости от этого сформировать итоговую строку так, чтобы она оставалась аккуратной. Учитывая слабую гибкость того, что можно вписать внутрь select-a. сей процесс превращается в тяжеловесную конструкцию со множеством скобок и вложенных операторов. Потому мне и понадобилась хранимая функция, в которой всё то же самое можно проделать намного элегантнее.

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

declare (переменные для курсора)
declare (переменная-счетчик)(количество_записей)
declare (курсор)
declare (переменная результат)

open курсор

счетчик=1
результат=''
количество записей=select count(*) from таблица where такая-то-связь

label: loop
    fetch курсор into переменные курсора
    обработать_переменные_курсора
# счетчик дописывается в итоговую строку, если мониторов больше одного
    результат=concat(результат, обработанные_переменные_курсора)
    счетчик++
end loop

return результат

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

    select MANUFACTURER,CAPTION,DESCRIPTION,SERIAL
        from (select (@mwr:=@mwr+1) kak,MANUFACTURER,CAPTION,DESCRIPTION,SERIAL
            from (select @mwr:=0) rt, monitors where hardware_id=gmhwid) pp
        where kak=RowNum into gmM, gmC, gmD, gmS;


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

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