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

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


пятница, 26 октября 2018 г.

bash: список имеющихся расширений файлов в каталоге и подкаталогах

Есть у меня сервер на самбе, вполне себе рабочий. В нем есть поддержка "корзины" (в отличие от микрософтовских серверов). Но вот какая штука: в корзину валятся всякие файлы, в т.ч. и временные. И за рабочий день их может набраться очень много.
Каждую ночь из "корзин" удаляются файлы старше 30 дней и просто очень толстые, а также - временные. Но иногда временных очень уж много. Стало быть, надо не помещать их в корзину вовсе.
Решение очевидно:

(/etc/samba/smb.conf или его инклюд)
[global]
    vfs objects = recycle
    recycle:keeptree=yes
    recycle:repository= .recycle/%U
    recycle:exclude=*.tmp,~*,*.~*

Однако, кроме трёх указанных типов (расширений имён) файлов могут удаляться и самые разные другие, в т.ч. и такие, которым незачем занимать место в "корзине". Просматривать всё вручную - не труЪ. Логично будет сначала составить список имеющихся расширений, а уже от него плясать. Но наконец-то я нашел ситуацию, для которой в никсах, кажется, нет подходящей утилиты - для выделения только расширения файла. Выделить имя - есть basename, выделить путь - dirname, а вот для выделения суффикса ничего нет.

Покопался, нашел замечательно:

(чего-то там) |awk -F . '{print $NF}'

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

# cd /var/samba/share
# find -depth -type f -wholename *recycle/* |awk -F . '{print $NF}'|sort|uniq

На выходе получаем отсортированный список уникальных расширений файлов, попавших в "корзины". Дальше осталось только выбрать самые ненужные и добавить их в список настроек виртуальной файловой системы "корзина".

Кроме того, на любимом StackExchange нашел еще приятное обсуждение по этому поводу.

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

# Из начала строки убираем самое длинное вхождение "*/", получаем имя файла с расширением 
filename="${fullpath##*/}";
# Берем подстроку от начала строки (поз. 0) до позиции, где начинается собственно имя файла
### TM: по сути, именно это делает команда dirname
directory="${fullpath:0:${#fullpath} - ${#filename}}";
# Отрезаем самую короткую подстроку, состоящую из точки и как минимум одного "обычного" символа, с конца имени файла
### TM: по сути, именно это делает команда basename
base="${filename%.[^.]*}";
# Берем подстроку от позиции "длина базового имени" до конца полного имени файла
extension="${filename:${#base} + 1}";
# Если на выходе у нас есть что-то в $extension, но ничего нет в $base, то файл был без расширения
if [[ -z "$base" && -n "$extension" ]]; then
  base=".$extension";
  extension="";
fi
echo -e "Оригинал:\t'$fullpath':\n\tПуть:\t'$directory'\n\tПолное имя файла:\t'$filename'\n\tБазовое имя:\t'$base'\n\tРасширение:\t'$extension'"
Специально оставил даже форматирование, как оно было в оригинале, только комментарии перетолмачил.

среда, 3 октября 2018 г.

bash: Получение читаемой информации о пользователе из ADDS

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

Но есть настроенный ldapsearch, которым мы и воспользуемся. Изначально фрагмент писался для получения данных о компах, поэтому переменная, которую ищем, называется $comp

NB! В итоговом массиве есть только одна переменная с индексом memberof, хотя пользователь может входить в несколько групп. Список групп я получаю более другими способами, поэтому ситуация в этом скрипте не анализируется. Возможно надо проверять значение индексера, и если он есть memberof, то дописывать значение параметра к переменной с таким индексом. Лично мне это просто не требуется.

#!/bin/bash
# похоже, что без промежуточного файла не обойтись - вывод ldapsearch напрямую не перехватывается
comp=$1
unset ldapData
# ldapData - ассоциативный, а не нумерованный массив!
declare -A ldapData
ldapsearch -o ldif-wrap=no -D ПОЛЬЗОВАТЕЛЬ -x -w "ПАРОЛЬ" "(cn=$comp)">/tmp/ldifDataFile
# список полей с датами, которые надо декодировать
# ведущий и хвостовой пробелы обязательны
datesList=" lastlogon pwdlastset badpasswordtime accountexpires "
while read ldiffPar ldiffData;do
  if [ "${ldiffPar:0:1}" == "#" ] || [ ${#ldiffPar} -eq 0 ]; then continue; else

# приводим ldiffPar к нижнему регистру
    ldiffPar=${ldiffPar,,}

# а для переменной-индекса убираем все двоеточия, сколько бы их там ни было
    indexer=${ldiffPar//:/}

# если два последних символа имени атрибута два двоеточия, значит он кодированный и нуждается в декодировании
    if [ ${ldiffPar: -2} == "::" ]; then
      ldapData[$indexer]="$( echo $ldiffData|base64 -d )"
    else
      ldapData[$indexer]="$ldiffData"
    fi
# если название атрибута в ADDS есть в списке $datesList, то переводим дату из
# формата MS в человекочитаемый
# не очень надежный способ поиска, поэтому ищем "пробел-индексер-пробел", а не просто "индексер"
    if  [[ "$datesList" = *" $indexer "*  ]]
    then
      ldapData[$indexer]=$( date -d @$(( ${ldapData[$indexer]}/10000000-11644473600 )) +%Y-%m-%d\ %H:%M:%S)
    fi
# отдельное внимание состоянию пользователя
    if [ $indexer == "useraccountcontrol" ]
    then
      isActive=$(( ${ldapData[$indexer]} & 2 ))
      if [ $isActive -eq 0 ]; then uacState="АКТИВЕН "; else uacState="не активен ";fi
      ldapData[$indexer]=$uacState${ldapData[$indexer]}
    fi
    echo ldapData[$indexer]=${ldapData[$indexer]}
  fi
done


На выходе получаем список всех непустых атрибутов пользователя.

среда, 8 августа 2018 г.

Замена GKSU в 18.04

Итак, кто-то решил, что gksu сильно устарела и более не требуется, поэтому она не входит ни в Debian, ни в его потомков, включая Ubuntu.

Порывшись по форумам, я узнал, что частичной заменой может служить использование pkexec:

pkexec имя_программы

При этом выводится стандартный графический запрос авторизации. Однако, этого недостаточно, потому что pkexec не передает вызываемой программе и не устанавливает переменные DISPLAY и XAUTHORITY, из-за чего графические программы в большинстве своем не запустятся.

$ env|grep -E "XAU|DISP"
DISPLAY=:0.0
XAUTHORITY=/home/troublemaker/.Xauthority

$ sudo su
...

# env|grep -E "XAU|DISP"
DISPLAY=:0.0
XAUTHORITY=/home/troublemaker/.Xauthority
# exit

$ pkexec bash
...

env|grep -E "XAU|DISP"
#

Из протокола видно, что pkexec, в отличие от sudo, не передает эти переменные окружения.

Исключение - XUbuntu, где для большинства штатных программ есть правила для policy kit, частью которого является pkexec. Но как быть, если нет соответствующих правил для нужной программы?

Пока что я нашел такой выход из положения (имитируем gksu/gksudo, запуская приложение с правами root из-под обычного пользователя, который входит в sudoers)

pkexec env DISPLAY="$DISPLAY" XAUTHORITY="$XAUTHORITY" имя_программы

Что происходит? Мы принудительно отдаем значения действующих переменных и запускаем программу от имени root не напрямую через pkexec, а косвенно, как один из аргументов команды env.
Коряво, наверное, но лучше, чем ничего. Возможно, удастся это дело запихать в alias, но проверять лень.

Да, еще есть какой-то хитрый способ запуска примерно так:

программа admin://полный_путь_к_файлу

Например:

gedit admin:///etc/fstab

Но у меня под 16.04 он не сработал, а включать ноут, где уже 18.04, для проверки тоже лень :-)

среда, 13 июня 2018 г.

И снова о просмотре логов squid и выводе полей в awk.

Очередной способ получить человеко-читаемое время в логах прокси-сервера.

awk '{print strftime("%Y-%m-%d %H:%M:%S",$1) " " substr($0, index($0,$2))}' FILENAME

Основная идея: по умолчанию поля в этом логе отделяются пробелами. Awk преобразует первое поле (дата и время в юникс-формате) в читаемый вид и выводит его. Далее печатается пробел, после которого печатается всё от начала второго поля до конца строки.

Как выяснилось, это самый быстрый способ заставить awk вывести "всё остальное", не перебирая поля последовательно в цикле.

Решение найдено здесь.

воскресенье, 10 июня 2018 г.

bash: поиск и замена

Sed, awk, grep - всё это здорово. Но это внешние программы, а что же по части встроенных? Их есть у меня!

${переменная/что/на что} - меняем первое вхождение "что" на "на что"
${переменная//что/на что} - меняем все вхождения "что" на "на что"

Например, есть переменная, в которой хранится путь:

filNam="sambas/samba201/shares.conf"

но из этого пути мне надо сформировать имя файла. Не выделить собственно имя из пути, а просто как-то изменить путь. Легко! Заменим все слэши на дефисы.

$ echo ${filNam/\//-}
sambas-samba201/shares.conf

$ echo ${filNam//\//-}
sambas-samba201-shares.conf

суббота, 9 июня 2018 г.

bash: сравнение строк без учета регистра

Понадобилось сравнить строки, конкретно - атрибуты CN и SAMAccountName в AD. Только не спрашивайте, на кой чёрт мне в баше надо сравнивать виндовые данные. Просто удобнее, чем километровые команды в PS.

Можно, конечно, сначала эти строки преобразовать к верхнему или нижнему регистру с помощью tr [:upper:] [:lower:], но это лишние команды и лишнее время выполнения скрипта, особенно если надо сравнивать много таких строк.
Чтобы избежать вызова этих лишних команд, воспользуемся встроенными возможностями:

${переменная,,} - (две запятых) привести переменную к нижнему регистру
${переменная^^} - (два циркумфлекса) привести переменную к верхнему регистру

Найдено здесь.

p.s. для вытаскивания нужных атрибутов из AD я пользуюсь как самбовской net, так и adtool, про которую уже рассказывал.

среда, 25 апреля 2018 г.

Zimbra: место на диске и протухшие сообщения

Я уже упоминал о проблемах с зимброй: в каталогах хранилища скапливаются древние файлы сообщений, которые давным давно удалены. До поры до времени я чистил их вручную, не зная, не аукнется ли это мне проблемами с доступом к п/я и т.п.
Оказалось, не всё так плохо. Хотя и не очень хорошо. Совершенно случайно выяснил, что это задокументированный баг, который нельзя устранить, но с последствиями которого можно бороться штатными средствами.
Итак, информация в зимбре хранится в более чем сотне БД MySQL. То есть, есть 100 штук баз mailboxgroupXXX, где XXX от 1 до 100, и несколько вспомогательных. Блобы, то есть, файлы почтовых сообщений, хранятся отдельно в "кластеризованном хранилище", и они-то и вызывают головную боль: движок MySQL не освобождает место, занятое ими.
В статье рассмотрено несколько вариантов, надо будет попробовать, а то совсем уже тоскливо.

Под катом текст статьи.

Теперь по месту на диске.
Обнаружил, что пропала или очень неактуальна статистика по использованию дискового пространства. Оказалось, что сам виноват: раньше она обновлялась с интервалом в 10 минут и заваливала меня сообщениями об исчерпании места, после чего я увеличил интервал до 5.5 часов. За что и поплатился.
В рабочем порядке уменьшил тот интервал до 3600 секунд, посмотрим, не полегчает ли сборщику статистики


среда, 4 апреля 2018 г.

WMIC в Ubuntu: продолжение

Продолжая начатую ранее тему опроса виндовых компов по WMI из-под линукса.

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

In the interest of knowledge sharing here is how to get wmic working on Ubuntu 16.04 LTS, the issue was the limit of the number of open files
ulimit -n 100000
cd /tmp
mkdir wmic
cd wmic

apt install autoconf gcc libdatetime-perl make build-essential g++ python-dev
wget http://www.opsview.com/sites/default/files/wmi-1.3.16.tar_.bz2
bunzip2 wmi-1.3.16.tar_.bz2
tar -xvf wmi-1.3.16.tar_
cd wmi-1.3.16/

vim Samba/source/pidl/pidl
:583 (to jump to line 583)
remove the word defined before @$pidl
:wq 

export ZENHOME=/usr
make "CPP=gcc -E -ffreestanding"
cp Samba/source/bin/wmic /bin
Should now be working.

Проверим...

понедельник, 19 февраля 2018 г.

Zimbra: частота предупреждений о заполненности диска

По умолчанию стоит 10 минут и это задалбывает - в ящике скапливают тонны бесполезных сообщений. Уменьшаем интервал:

zmlocalconfig -e zmstat_disk_interval=19800

19800 секунд составляет 5.5 часов

Zimbra: статистика по размерам почтовых ящиков

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

Но это ж линукс, детка!

zimbra@server:$ zmprov gqu имя_сервера|sort -k 3 -n|column -t

и получаем красивую ровную табличку, отсортированную по правому столбцу, где указан, собственно, размер занятого места. (в первом столбце адрес учётки, во втором - квота для нее)

gqu -- GetQuoteUsage

-k 3 -- сортировать по третьему столбцу
-n -- сортировать числа как числа, чтобы 20 шло после 19, а не после 10

-t -- подобрать подходящие для красивой таблички ширины столбцов

вторник, 30 января 2018 г.

Отключение IPv6 в Ubuntu: второй способ

Я уже писал про отключение поддержки IPv6. Но, как оказалось, можно сделать проще.

1. sudo nano /etc/default/grub

В строке GRUB_CMDLINE_LINUX="xxxxx" после xxxxxx дописываем параметр для ядра: :

GRUB_CMDLINE_LINUX="xxxxx ipv6.disable=1"

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

GRUB_CMDLINE_LINUX="ipv6.disable=1"

2. sudo update-grub
3. sudo reboot