~s - скрипты-утилиты — различия между версиями
м |
|||
(не показано 38 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
+ | [[Категория:Разработка]] | ||
По адресу [{{SVN|vitalif/trunk/scripts/}} ~/s] я поддерживаю некоторое количество простеньких полезных скриптов для решения различных задачек. | По адресу [{{SVN|vitalif/trunk/scripts/}} ~/s] я поддерживаю некоторое количество простеньких полезных скриптов для решения различных задачек. | ||
На данной странице описаны наиболее применимые из них, остальные можно увидеть по [{{SVN|vitalif/trunk/scripts/}} ссылке]. | На данной странице описаны наиболее применимые из них, остальные можно увидеть по [{{SVN|vitalif/trunk/scripts/}} ссылке]. | ||
− | == [{{SVN|vitalif/trunk/scripts/ | + | = Демоны = |
+ | |||
+ | [[rupedia:Daemon|Демоны]] и около-демонические скрипты. | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/rsync-timemachine.pl|co}} rsync-timemachine.pl] == | ||
+ | |||
+ | Инкрементальные (на файловом уровне) бэкапы (типа «Time Machine») на основе [[rupedia:Rsync]], для любой unix-машины :) с небольшой дополнительной плюшкой — на Debian/Ubuntu дистрибутивах дампит и бэкапит MySQL-базы данных. | ||
+ | |||
+ | По месту назначения создаёт папочки с именами вида YYYY-MM-DD, названные в честь даты очередного бэкапа (текущей на момент запуска скрипта), и туда rsync’ом заливаются заданные директории. | ||
+ | |||
+ | '''А теперь Killer-Feature:''' используется опция <tt><nowiki>--link-dest</nowiki></tt> относительно последнего бэкапа, и они становятся инкрементальными! С этой опцией rsync сравнивает файл с предыдущей версией, и если он не менялся, создаёт [[rupedia:Жёсткая ссылка|жёсткую ссылку]] на неё. Таким образом дублирование файлов убирается на уровне ФС. | ||
+ | |||
+ | Чрезмерно старые бэкапы скрипт тоже удаляет сам — для этого ему нужно задать максимальный возраст бэкапа в днях. Всё, что старее, будет удаляться. Директории с именами, не равными дате в формате YYYY-MM-DD, скрипт не трогает, правда, если YYYY-MM-DD нет вообще, то бэкап будет сделан относительно не-YYYY-MM-DD-каталога. | ||
+ | |||
+ | На регулярность бэкапов скрипту пофигу — когда вызовешь, тогда и будет сделан очередной бэкап. Соответственно, задаётся регулярность просто включением скрипта в cron с нужным интервалом. Двойного одновременного запуска можно не бояться — скрипт отслеживает и его, с помощью pid-файла. | ||
+ | |||
+ | Синтаксис запуска: <tt><nowiki>perl rsync-timemachine.pl -s МЕСТО_НАЗНАЧЕНИЯ [-A 'ОПЦИИ_RSYNC'] [-k ВОЗРАСТ] [-p PID-ФАЙЛ] [-D ПРОПУСТИТЬ_БД] ДИРЕКТОРИИ...</nowiki></tt> | ||
+ | |||
+ | * МЕСТО_НАЗНАЧЕНИЯ в rsync’овском синтаксисе. | ||
+ | * ОПЦИИ_RSYNC — опции, которые нужно передавать во все вызовы rsync (например, <tt><nowiki>--password-file=/etc/rsync.secret</nowiki></tt>). | ||
+ | * ВОЗРАСТ — максимальный возраст бэкапа в днях. Если опцию не передавать — скрипт ничего не удаляет. | ||
+ | * PID-ФАЙЛ — даёт возможность (не шибко нужную, но мало ли) переопределить расположение pid-файла, равное по умолчанию <tt>/var/run/timemachine.pid</tt>. | ||
+ | * ДИРЕКТОРИИ — собственно, что бэкапим. Бэкапятся без полного пути, то есть например /var/backups/mysql попадёт по адресу МЕСТО_НАЗНАЧЕНИЯ/YYYY-MM-DD/mysql. | ||
+ | * ПРОПУСТИТЬ_БД — задаёт регулярное выражение для исключения баз данных из дампа. | ||
+ | |||
+ | {{SVN|vitalif/trunk/scripts/rsync-timemachine.pl|markup}} | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/logautocommit.pl|co}} logautocommit.pl] == | ||
+ | |||
+ | Идея скрипта: простой автоматический версионный контроль конфигурации сервера. Большая часть конфигурации в UNIX-системах, как известно, находится в /etc, поэтому в первую очередь нужно версионировать содержимое /etc. Причём, не так важно, куда коммитить изменения — скорее всего, подойдёт локальный репозиторий любой системы управления версиями (скажем, Subversion), но важно, чтобы: | ||
+ | * Изменения записывались автоматически. | ||
+ | * Записывалось, кем внесено изменение — очень желательно сохранять IP-адрес удалённой сессии, потому что системным пользователем почти наверняка будет root. | ||
+ | * Файлы коммитились не сразу, а через промежуток времени, чтобы в процессе редактирования каждое нажатие F2 (сохранение) не добавляло по коммиту. | ||
+ | * Изменения, вносимые менеджером пакетов, не учитывались. | ||
+ | |||
+ | Итак, встречаем скрипт. Он использует [http://linux.die.net/man/8/auditd auditd] для отслеживания изменений файлов в /etc — это наиболее оптимально в терминах производительности. Посему первый шаг — установить и настроить auditd: | ||
+ | |||
+ | <code-bash> | ||
+ | apt-get install auditd | ||
+ | echo -w /etc/ -p wa >> /etc/audit/audit.rule # логгируем запись в /etc/ | ||
+ | /etc/init.d/auditd reload | ||
+ | </code-bash> | ||
+ | |||
+ | Второй шаг — создать файл /etc/logautocommit-log4perl.conf со следующим содержимым: | ||
+ | <pre> | ||
+ | log4perl.logger.ConfAutoCommit = INFO, ConfAutoCommit | ||
+ | log4perl.appender.ConfAutoCommit = Log::Log4perl::Appender::File | ||
+ | log4perl.appender.ConfAutoCommit.filename = /var/log/audit/autocommit.log | ||
+ | log4perl.appender.ConfAutoCommit.layout = PatternLayout | ||
+ | log4perl.appender.ConfAutoCommit.layout.ConversionPattern = %d %5p %C:%L %m %n | ||
+ | log4perl.appender.ConfAutoCommit.create_at_logtime = 1 | ||
+ | </pre> | ||
+ | |||
+ | Здесь /var/log/audit/autocommit.log — путь к логу самой коммитилки. | ||
+ | |||
+ | Третий шаг: создать репозиторий и рабочую копию, добавить в них конфиги, которые уже лежат в /etc, и которые уже менялись (по вкусу). | ||
+ | <source lang="bash"> | ||
+ | svnadmin create /root/svn-etc-repo | ||
+ | svn co file:///root/svn-etc-repo /root/svn-etc | ||
+ | # cp /etc/… /root/svn-etc | ||
+ | svn add /root/svn-etc/* | ||
+ | svn ci -m 'initial configs' | ||
+ | </source> | ||
+ | |||
+ | И, наконец, запустить logautocommit.pl и прописать его запуск в /etc/rc.local, с нужными аргументами. | ||
+ | |||
+ | Использование: | ||
+ | ./logautocommit.pl [ОПЦИИ] | ||
+ | или | ||
+ | ./logautocommit.pl /etc/logautocommit.conf | ||
+ | Здесь /etc/logautocommit.conf — конфиг скрипта, может содержать те же [ОПЦИИ], по одной на строку. | ||
+ | |||
+ | Опции: | ||
+ | <tab sep="||" class="wikitable" head="top"> | ||
+ | Формат 1 || Формат 2 || Описание || По умолчанию | ||
+ | -a XXX || log=XXX || Путь к логу auditd || /var/log/audit/audit.log | ||
+ | -d XXX || etcdir=XXX || Путь к версионируемой директории || /etc | ||
+ | -w XXX || workdir=XXX || Путь к рабочей копии || /root/svn-etc | ||
+ | -e XXX || exclude=XXX || Исключить изменения файлов с именами, подпадающими под регулярное выражение XXX || <nowiki>^/etc/(alternatives|rc\d?\.d)|(^|/)(\.#|mtab|ld\.so\.cache|adjtime|motd$)|\.dpkg-(new|dist)$|\.default$|/\.svn/</nowiki> | ||
+ | -x XXX || exclude_exe=XXX || Исключить изменения, сделанные приложения с именами образа, подпадающими под регулярное выражение XXX || <nowiki>(^|/)dpkg$</nowiki> | ||
+ | -l XXX || log_config=XXX || Использовать файл XXX как конфиг для логгера {{CPAN|Log::Log4perl}} || /etc/logautocommit-log4perl.conf | ||
+ | -c XXX || chktime=XXX || Проверять изменения файлов через XXX секунд || 60 | ||
+ | -m XXX || comtime=XXX || Коммитить не чаще, чем в XXX секунд || 300 | ||
+ | -p XXX || polltime=XXX || Интервал спячки после прерванного блокировующего чтения || 0.5 | ||
+ | -b || background=1 || Уйти в фоновый режим после запуска || Да | ||
+ | -f || background=0 || Не уходить в фоновый режим, полезно для отладки || Нет | ||
+ | </tab> | ||
+ | |||
+ | * FIXME: проверить, как скрипт работает с символическими ссылками. | ||
+ | * FIXME: проверка того, что изменение сделано через dpkg, работает не до конца корректно и иногда коммитятся лишние файлы, не менявшиеся руками | ||
+ | |||
+ | Кроме содержимого /etc, полезно также версионировать списки установленных пакетов системного менеджера пакетов и скриптовых языков типа Perl, PHP, Python, Ruby — это проще всего сделать, добавив в крон скрипт со следующим содержимым: | ||
+ | |||
+ | <source lang="bash"> | ||
+ | COLUMNS=3000 dpkg -l > /etc/packages-status-debian | ||
+ | perl -MCPAN -e "CPAN::Shell->r" > /etc/packages-status-perl | ||
+ | pear list > /etc/packages-status-php | ||
+ | gem list > /etc/packages-status-ruby | ||
+ | </source> | ||
− | [ | + | Для Python аналогично простой команды нет, но можно воспользоваться скриптом [[#pkgsearch.py|pkgsearch.py]] с данной страницы: |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | python [[#pkgsearch.py|pkgsearch.py]] > /etc/packages-status-python | |
− | + | Ещё может оказаться полезным версионировать схемы всех баз данных, но это уже частично относится к разработке. | |
== FastPerl == | == FastPerl == | ||
Строка 35: | Строка 126: | ||
Init-скрипт прилагается, по умолчанию выполняется под пользователем www-data и группой www-data, логи в /var/log/fastperl.log, сокет в /var/run/fastperl.socket, PID-файл в /var/run/fastperl.pid, без ограничения. Init-скрипт понимает /etc/default/fastperl с переменными: | Init-скрипт прилагается, по умолчанию выполняется под пользователем www-data и группой www-data, логи в /var/log/fastperl.log, сокет в /var/run/fastperl.socket, PID-файл в /var/run/fastperl.pid, без ограничения. Init-скрипт понимает /etc/default/fastperl с переменными: | ||
− | * USER=user:group | + | * USER=user: group |
* LOGFILE= | * LOGFILE= | ||
* SOCKET= | * SOCKET= | ||
Строка 47: | Строка 138: | ||
* Основан на [http://wiki.codemongers.com/NginxSimpleCGI http://wiki.codemongers.com/NginxSimpleCGI]. | * Основан на [http://wiki.codemongers.com/NginxSimpleCGI http://wiki.codemongers.com/NginxSimpleCGI]. | ||
− | == | + | == gcauthcd.pl == |
− | + | Клиент для МиГ-Телекомовской авторизации (''Gagarin-Club AUTHentication Client Daemon''), переписанный на Perl’е. Исходников реального gcauthcd я не видел, данный сделан чисто исходя из тривиального реверс-инжиниринга. Сам его и <s>использую</s> использовал, по причине того, что SSL-сертификаты у них давно протухли, виндовый gcauthcd это не парит, а реальный линуксовый работать отказывается, а хакнуть и заставить его не получается по причине статической линковки. | |
− | + | Логин-пароль берёт либо из /etc/gcauth.passwd, либо из файла указанного <code>./gcauthcd.pl -c /path/to/password.file</code>, в формате «LOGIN:PASSWORD». Опция --fg даёт возможность не сворачивать его в background, --force — запускать при неработающей авторизации, время от времени открыть доступ он тогда всё равно будет пытаться. | |
− | + | * {{SVN|vitalif/trunk/scripts/gcauthcd.pl|markup}} | |
− | + | == gamin.pl == | |
− | + | '''Пригодный для автоматизации''' скрипт для мониторинга изменений файлов и директорий с помощью модуля {{CPAN|Sys::Gamin}} (использующего реализацию FAM’а (File Alternation Monitor) «libgamin») версии 0.1. События выводятся на STDOUT в две колонки, скрипт живёт, пока не прибьют сигналом. Первая — имя события (одно из: change, delete, start_exec, stop_exec, create, move, ack, exist, end_exist), вторая — имя файла. К имени события может быть дописаны суффиксы: | |
+ | * «|D» = «путь является каталогом и запрошен нерекурсивный режим» | ||
+ | * «|M» = «запрошен рекурсивный режим, запускаю мониторинг каталога» | ||
+ | * «|C» = «путь удалён, отменяю мониторинг каталога» | ||
− | + | Соответственно, скрипт можно использовать в каких-нибудь скриптах (шелл или не очень) как монитор ФС, читать и парсить его вывод, и действовать по ситуации. | |
− | + | Синтаксис вызова: | |
+ | ./gamin.pl [-n] /directory1 /directory/2 some.file | ||
− | + | Опция «-n» означает «мониторить нерекурсивно». | |
− | * {{SVN|vitalif/trunk/scripts/ | + | * {{SVN|vitalif/trunk/scripts/gamin.pl|markup}} |
− | == | + | == bind9-forwarders-resolvconf == |
− | Скрипт для | + | Скрипт для обновления [http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2557350 forwarder’ов DNS-сервера bind] при DHCP-обновлении набора доступных DNS. То есть, это скрипт для установки на машину-роутер, потому что, предположительно, только машина-роутер может иметь и внешний интерфейс, на котором работает DHCP, получающий обновления DNS провайдера, и bind, которому нужны корректные forwarder’ы. |
− | + | Скрипт сильно похож на стандартный дебиановский [[DebianMagicResolvConfBind|/etc/resolvconf/update.d/bind]] и тоже предназначен для установки в /etc/resolvconf/update.d/, отличается от стандартного следующим: | |
+ | * Написан на perl ⇒ не использует «особую уличную магию» с кучей вызовов <tt>sed</tt> и посему не глючит | ||
+ | * Берёт /etc/bind/named.conf.options.in, заменяет в нём $FORWARDERS на список обнаруженных DNS, разделённых точками с запятой (но без; в конце, то есть надо писать forwarders { $FORWARDERS; }) и записывает в <tt>/etc/bind/named.conf.options</tt>. | ||
+ | * Не дёргает без надобности (когда конфиги не менялись) rndc reconfig. | ||
− | * {{SVN|vitalif/trunk/scripts/ | + | * {{SVN|vitalif/trunk/scripts/bind9-forwarders-resolvconf|markup}} |
+ | |||
+ | = Команды = | ||
+ | |||
+ | Простые полезные консольные команды, которых часто не хватает в UNIX-окружении. | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/cpshift.c|co}} cpshift.c] == | ||
+ | |||
+ | Простая C-программка для копирования кусков файлов. Нечто типа dd, но удобнее, потому что | ||
+ | * Не требует задавать смещения, кратные размеру буфера => простая задача «вытащить X байт из файла, начиная с Y» выполняется в ПИЦОТ раз быстрее, потому что используется большой буфер, а не dd bs=1. | ||
+ | * Поддерживает обратный порядок копирования => позволяет корректно перемещать данные внутри одного файла (например, разделы на диске!) ВПЕРЁД. Если имя входного файла равно имени выходного, то сама выбирает нужный порядок — вперёд или назад — по разнице смещений. | ||
+ | * Поддерживает отрицательные входные смещение и размер — тогда, как в substr в Perl/PHP, они считаются от конца входного файла. | ||
+ | * Понимает шестнадцатеричные и восьмеричные значения параметров — удобно, потому что не нужно обрамлять их в $(()) или конвертировать в десятичные значения. | ||
+ | * Печатает прогресс копирования в %. | ||
+ | |||
+ | Короче, может быть, оно и велосипед, но с первого взгляда я такой стандартной unix-тулы не нашёл, а dd, простите, дебилен. | ||
+ | |||
+ | Компилировать тривиально: | ||
+ | |||
+ | gcc -o cpshift cpshift.c | ||
+ | |||
+ | Использовать тоже просто, вот только опций поприбавилось :) | ||
+ | |||
+ | ./cpshift [OPTIONS] infile [outfile] | ||
+ | |||
+ | * Копирует кусок файла 'infile' в 'outfile'. | ||
+ | * 'infile' может быть равен 'outfile', тогда данные перемещаются в одном файле. | ||
+ | * Никогда не обрезает длину выходного файла. | ||
+ | * Если 'outfile' не задан или равен '-', то данные копируются на STDOUT. 'infile' также может быть '-', в этом случае данные копируются из STDIN. Однако, эти потоки всё равно должны поддерживать позиционирование, что cpshift с ними работал. | ||
+ | * Все численные параметры могут быть десятичными (например, 256), шестнадцатеричными (0x1AB) или восьмеричными (0127). | ||
+ | |||
+ | Опции: | ||
+ | * --skip SKIP_BYTES — смещение от начала входного файла в байтах. Может быть отрицательным, и тогда считается от конца входного файла. | ||
+ | * --size SIZE_BYTES — максимальный размер копируемой области в байтах. Может быть отрицательным, и тогда копируется всё до позиции (размер_файла-SIZE_BYTES). | ||
+ | * --skip-output SKIP_IN_OUTPUT — смещение в выходном файле в байтах. | ||
+ | * --buffer BUFFER_SIZE — размер буфера (сколько байт копировать за раз). По умолчанию 1 Мб (0x100000 байт). | ||
+ | * --reverse — задаёт обратный порядок копирования. В принципе, опция нужна редко, так как если входной файл равен выходному, то нужный порядок выбирается на основе смещений автоматически. | ||
+ | |||
+ | === English help === | ||
+ | |||
+ | ./cpshift [OPTIONS] infile [outfile] | ||
+ | |||
+ | * Copies part of 'infile' to 'outfile'. | ||
+ | * Never truncates the output file. | ||
+ | * 'infile' can be equal to 'outfile', then data is moved within one file. | ||
+ | * All numeric parameters may be decimal (256), hexadecimal (0x1AB) or octal (0127). | ||
+ | * '-' can be specified as 'infile' (means STDIN) or 'outfile' (means STDOUT). Note that it must be anyway seekable for cpshift to work with it. | ||
+ | |||
+ | Options: | ||
+ | * --skip SKIP_BYTES — skip to this position inside the input file. SKIP_BYTES can be negative; if so, it is counted from the end of input file. | ||
+ | * --size SIZE_BYTES — copy at most this count of bytes. SIZE_BYTES can be negative; if so, it means copy up to the (-SIZE_BYTES)'th byte from the end of input file. | ||
+ | * --skip-output SKIP_IN_OUTPUT — skip to this position inside the output file. | ||
+ | * --buffer BUFFER_SIZE — copy this count of bytes at once (default 1 MB = 0x100000 bytes). | ||
+ | * --reverse — use reverse copying order. In most cases you don’t need to set this manually because when you’re moving data within one file, the correct copying order is selected automatically based on offsets (reverse order is used when moving data forward, forward order is used when moving data backward). | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/move-mdadm0.9.c|co}} move-mdadm0.9.c] == | ||
+ | |||
+ | Простая утилита для перемещения mdadm’овского суперблока при изменении размера RAID-разделов. Лицензия: GNU GPL 3.0 или более поздняя, в том виде, в котором опубликована Фондом Свободного Программного Обеспечения. | ||
+ | |||
+ | Компиляция и использование: | ||
+ | |||
+ | gcc -o move-mdadm0.9 move-mdadm0.9.c | ||
+ | ./move-mdadm0.9 device old_size_in_bytes new_size_in_bytes | ||
+ | |||
+ | Есть несколько версий суперблока mdadm — 0.90, 1.0, 1.1 и 1.2. Версии 1.1 и 1.2 располагаются в начале дискового раздела и поэтому не нуждаются в перемещении при изменении его размера; версии 0.90 и 1.0 суперблока, однако, располагаются в конце раздела и поэтому при изменении размера раздела их нужно перемещать. | ||
+ | |||
+ | Стандартный подход для этого — удалять диски из массива по одному, изменять их размер и добавлять обратно, опять-таки по одному. Это долго, так как требует синхронизации данных (resync) после добавления каждого диска. Только после завершения нескольких resync вы сможете запустить <tt><nowiki>mdadm --grow</nowiki></tt>. | ||
+ | |||
+ | Чтобы этого не делать и была написана данная утилита. С ней вы можете просто остановить массив (<tt><nowiki>mdadm --stop</nowiki></tt>), изменить размеры всех разделов, запустить {{cmd|./move-mdadm0.9 <раздел> <старый_размер_в_байтах> <новый_размер_в_байтах>}} | ||
+ | на каждом разделе и запустить массив обратно, после чего он будет сразу готов для выполнения команды <tt><nowiki>mdadm --grow</nowiki></tt>. | ||
+ | |||
+ | === English help === | ||
+ | |||
+ | Simple tool that allows to move mdadm v0.90 and v1.0 superblocks after resizing a device. License: GNU GPL 3.0 or later, as published by the Free Software Foundation. | ||
+ | |||
+ | Compiling and usage: | ||
+ | |||
+ | gcc -o move-mdadm0.9 move-mdadm0.9.c | ||
+ | ./move-mdadm0.9 device old_size_in_bytes new_size_in_bytes | ||
+ | |||
+ | mdadm superblock is the metadata structure stored on devices/partitions participating in a software raid array. There are several versions of metadata format, namely v0.90, v1.0, v1.1 and v1.2. v1.1 and v1.2 superblocks are stored in the beginning and thus do not need moving when the raid partition is resized. However, v0.90 and v1.0 superblocks are stored in the end of the partition, so they need to be moved during resize, or mdadm won’t be able to find them. | ||
+ | |||
+ | The standard approach is to remove, resize and re-add disks from the array one by one, but it requires a resync after re-adding each disk, which takes a long time and is basically redundant. Only after all resyncs, you’ll be able to run <tt><nowiki>mdadm --grow</nowiki></tt>. | ||
+ | |||
+ | With this tool, you can just stop the array, resize all partitions, run {{cmd|./move-mdadm0.9 <device> <old_device_size_in_bytes> <new_device_size_in_bytes>}} | ||
+ | on each of them, start the array again and it will be immediately ready for | ||
+ | <tt><nowiki>mdadm --grow</nowiki></tt>. | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/bindiff.c|markup}} bindiff.c] == | ||
+ | |||
+ | Побайтно сравнивает два файла и печатает разницу между ними в шестнадцатеричном виде, в формате «адрес: старые_данные новые_данные» (точно такой формат использовался для патчей телефонов Siemens программой V_KLay): | ||
+ | <pre> | ||
+ | 00C01582: 0145 0000 | ||
+ | 00C01587: 02 00 | ||
+ | ... | ||
+ | </pre> | ||
+ | |||
+ | Компилировать просто — {{cmd|gcc -o bindiff bindiff.c}}. Использовать так — {{cmd|./bindiff file1 file2}}. | ||
+ | |||
+ | * {{SVN|vitalif/trunk/scripts/bindiff.c}} | ||
== fromto == | == fromto == | ||
Строка 85: | Строка 282: | ||
* {{SVN|vitalif/trunk/scripts/fromto|markup}} | * {{SVN|vitalif/trunk/scripts/fromto|markup}} | ||
− | == | + | == intdu, intsort == |
− | + | «Интерактивный» консольный sort — не ждёт полного результата, а показывает последние LINES строк, обновляющиеся по каждой строке, полученной со стандартного ввода (LINES = `tput lines` = число строк в текущем окне терминала). Строки, «уходящие» назад за пределы окна терминала, отсортированными не являются и смотреть их не надо. | |
− | + | Применение: команда «intdu», интерактивно подсчитывающая размеры подпапок текущего каталога и показывающая вам LINES самых больших папок. | |
− | + | ||
− | + | * {{SVN|vitalif/trunk/scripts/intdu|markup}} | |
+ | * {{SVN|vitalif/trunk/scripts/intsort|markup}} | ||
− | + | == whichpm == | |
− | + | ||
− | + | Аналог which для Perl-модулей — говорит, где лежит тот или иной модуль. | |
− | + | $ ~/s/whichpm Encode | |
+ | /usr/lib/perl/5.10/Encode.pm | ||
− | + | * {{SVN|vitalif/trunk/scripts/whichpm|markup}} | |
− | + | == unzip.pl == | |
− | + | Используйте вместо стандартного unzip — после разархивации перекодирует кривые имена файлов, бывших русскими внутри архива. | |
− | + | * {{SVN|vitalif/trunk/scripts/unzip.pl|markup}} | |
− | + | == convert-filenames == | |
− | + | ||
− | + | Скрипт для перекодирования имён файлов в каталоге из одной кодировки в другую. Сам ничего не выполняет, только выводит на STDOUT список команд mv A B. Пример использования: | |
− | + | ./convert-filenames /path/ cp1251 koi8-r | sh | |
− | * {{SVN|vitalif/trunk/scripts/ | + | * {{SVN|vitalif/trunk/scripts/convert-filenames|markup}} |
− | == | + | == timestamp == |
− | + | Простая утилита преобразования дат для тех, кто привык к коду MediaWiki ([[mediawikiwiki:Manual:WfTimestamp|wfTimestamp()]]). | |
− | + | ./timestamp <желаемый_формат_даты> <дата> | |
− | + | ||
− | + | ||
− | + | ||
− | + | На входе дата в любом из желаемых форматов. Единственное замечание — чтобы корректно парсить даты в формате TS_MW, нужно передавать их с пробелом в начале, типа <tt>./timestamp TS_UNIX ' 20100101000000'</tt>, чтобы «сплошное число» можно было отличить от UNIX времени. | |
− | + | Форматы даты/времени поддерживаются следующие: | |
+ | ;TS_UNIX: UNIX время (число секунд с 01.01.1970). | ||
+ | ;TS_DB: YYYY-MM-DD HH:MM:SS. | ||
+ | ;TS_DB_DATE: YYYY-MM-DD. | ||
+ | ;TS_MW: YYYYMMDDHHMMSS. | ||
+ | ;TS_ISO_8601: YYYY-MM-DD'''T'''HH:MM:SS. | ||
+ | ;TS_EXIF: YYYY:MM:DD HH:MM:SS. | ||
+ | ;TS_RFC822: Wday, DD Mon YYYY HH:MM:SS +ZZZZ. Wday — 3-буквенная латинская аббревиатура дня недели, Mon — 3-буквенная латинская аббревиатура месяца, ZZZZ — зона, смещение от GMT в формате HHMM (часы, минуты). | ||
+ | ;TS_ORACLE: DD-Mon-YYYY HH.MM.SS AM|PM. | ||
− | + | == convert-many == | |
− | + | Скрипт для перекодирования множества изображений из одного формата в другой с помощью [http://www.graphicsmagick.org/ GraphicsMagick] или [http://www.imagemagick.org/ ImageMagick], возможно, в несколько потоков. Пример использования: | |
− | + | find /path/ -name *.png | xargs ./convert-many png jpg 2 | sh | |
− | + | * {{SVN|vitalif/trunk/scripts/convert-many|markup}} | |
− | + | == bashrc.any == | |
− | + | Команды для переключения кодировок koi8, utf8, cp1251 в KDE Konsole из консоли, не прибегая к помощи менюшек. Версии для KDE [{{SVN|vitalif/trunk/scripts/bashrc.any|markup}} 4.x] и [http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/bashrc.any?view=markup&revision=704 3.x]. | |
− | * [ | + | |
+ | А команда yc вам не нужна, удаляйте её. :) | ||
+ | |||
+ | = Хелперы = | ||
+ | |||
+ | Полезные инструменты для реализации какого-то однократного действия, слишком большие для того, чтобы называть их просто консольной командой. | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/calc-mem.pl|markup}} calc-mem.pl] == | ||
+ | |||
+ | Подсчёт '''[[wikipedia:Copy-on-write#Copy-on-write_in_virtual_memory|разделяемой]] и неразделяемой''' памяти, используемой процессами в Linux. | ||
+ | |||
+ | Скрипт предназначен для оценки требований памяти каких-нибудь форкающихся демонов типа apache2 httpd, php5-fpm и так далее. | ||
+ | |||
+ | Использование: | ||
+ | ; ./calc-mem.pl -c php-fpm: Разделить системные процессы на две группы — те, у которых команда запуска содержит регулярное выражение «php-fpm» и те, у которых не содержит, и вывести ''средние, суммарные и максимальные'' значения разделяемой и неразделяемой памяти по каждой группе. | ||
+ | ; ./calc-mem.pl -p 1584: Просто вывести разделяемую и неразделяемую память процесса с pid 1584. | ||
+ | |||
+ | * [{{SVN|vitalif/trunk/scripts/calc-mem.pl|co}} Скачать calc-mem.pl] | ||
+ | |||
+ | == Команды git == | ||
+ | |||
+ | Хелперы для системы контроля версий git, написанные на чём попало. Они имеют имена вида «git-xxx» и если такой скрипт подложить в /usr/lib/git-core/, то «git xxx» вызовет этот скрипт. | ||
+ | |||
+ | === [{{SVN|vitalif/trunk/scripts/git-ff|markup}} git-ff] === | ||
+ | |||
+ | Типа git pull, но удобнее — автоматически делает Fast-Forward всем локальным веткам, связанным с удалёнными. | ||
+ | |||
+ | === [{{SVN|vitalif/trunk/scripts/git-info|markup}} git-info] === | ||
+ | |||
+ | Выводит некую информацию о текущем репозитории, типа svn info. | ||
+ | |||
+ | === [{{SVN|vitalif/trunk/scripts/git-sparse-checkout|markup}} git-sparse-checkout] === | ||
+ | |||
+ | Делает из обычной рабочей копии Sparse Checkout, то есть, сохраняет только заданные в командной строке пути, а остальные игнорирует. | ||
+ | |||
+ | === [{{SVN|vitalif/trunk/scripts/git-truncate|markup}} git-truncate] === | ||
+ | |||
+ | Скрипт для кастрации истории git-репозитория. «git-truncate REV» угробит все ревизии старше REV и заменит их одной, включающей в себя состояние на момент REV. Дочерние ревизии REV будут пересажены наверх новой. Всё это, правда, произойдёт только в текущей ветке, другие ветки будут сохранены. Будет сохранена и предыдущая версия истории, если к ней ведёт путь от одной из других веток. | ||
== pgraph-dot == | == pgraph-dot == | ||
Строка 150: | Строка 388: | ||
Использовать в каталоге Mercurial-репозитория следующим образом: <tt>pgraph-dot имяфайла.формат</tt>, где формат — один из поддерживаемых Graphviz форматов вывода (png, svg, dot и т. п.) | Использовать в каталоге Mercurial-репозитория следующим образом: <tt>pgraph-dot имяфайла.формат</tt>, где формат — один из поддерживаемых Graphviz форматов вывода (png, svg, dot и т. п.) | ||
− | * [ | + | * [{{SVN|vitalif/trunk/scripts/pgraph-dot|markup}} Скачать pgraph-dot] |
+ | |||
+ | Пример такого графа: | ||
+ | |||
+ | '''[[Файл:PgraphDotExample.svg|400px]]''' | ||
== sgold-note.pl == | == sgold-note.pl == | ||
Строка 159: | Строка 401: | ||
* [http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/sgold-note.pl?revision=748&view=markup sgold-note.pl] | * [http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/sgold-note.pl?revision=748&view=markup sgold-note.pl] | ||
+ | |||
+ | = Персонализация = | ||
+ | |||
+ | Патчи, модификации, файлы настроек, юзер-скрипты. | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/googletracking-b-gone.user.js|co}} googletracking-b-gone.user.js] == | ||
+ | |||
+ | «Google Tracking B Gone» — скрипт отключает дебильные гугловские редиректы при кликах по ссылкам. То есть в поиске будут '''реальные ссылки на страницы''', а не ссылки на гугловский URL, перенаправляющий на реальную страницу только после записи информации о вашем клике и мешающий копировать ссылки по правой кнопкею | ||
+ | |||
+ | Данная версия поддерживает как Firefox (Greasemonkey), так и Chrome с Opera, и постоянно используется мною в этих браузерах. Так что отсутствие глюков гарантировано. | ||
+ | |||
+ | В Opera для установки юзерскрипта надо создать любую папочку под свои юзер-скрипты, положить туда скачанный файл и прописать её в <tt>Preferences → Advanced → Content → JavaScript options → User JavaScript folder</tt>. | ||
+ | |||
+ | В Chrome — просто кликнуть «Скачать» и согласиться с установкой. | ||
+ | |||
+ | В Firefox — сначала поставить [https://addons.mozilla.org/ru/firefox/addon/greasemonkey/ Greasemonkey], потом так же кликнуть «Скачать» и согласиться с установкой. | ||
+ | |||
+ | * [http://userscripts.org/scripts/source/120330.user.js Скачать] | ||
+ | * [{{SVN|vitalif/trunk/scripts/googletracking-b-gone.user.js|markup}} Просмотр скрипта в моём svn] | ||
+ | * [http://userscripts.org/scripts/show/120330 Этот же скрипт на userscripts.org] | ||
+ | |||
+ | == [{{SVN|vitalif/trunk/scripts/googlefocus.user.js|co}} googlefocus.user.js] == | ||
+ | |||
+ | Ещё один пользовательский скрипт для гуглового поиска — на этот раз для тех, кого, как и меня, бесит то, что по умолчанию гугл при каждом нажатии любой буквенно-цифровой клавиши на клавиатуре автоматически фокусирует поле ввода. Данный скрипт отключает это поведение и, как и предыдущий, поддерживает Firefox/Chrome/Opera. | ||
+ | |||
+ | * [http://userscripts.org/scripts/source/132237.user.js Скачать] | ||
+ | * [{{SVN|vitalif/trunk/scripts/googlefocus.user.js|markup}} Просмотр скрипта в моём svn] | ||
+ | * [http://userscripts.org/scripts/show/132237 Этот же скрипт на userscripts.org] | ||
+ | |||
+ | == mc.color == | ||
+ | |||
+ | Две цветовые схемы Midnight Commander: одна на чёрном фоне, вторая на чёрном фоне с красными менюшками, я её использую, чтобы сразу отличать боевые сервера от локальной машины. | ||
+ | |||
+ | MC >= 4.7.0, копировать в <tt>/usr/share/mc/skins</tt>, а в mc.ini прописывать <tt>skin=имя</tt>: | ||
+ | |||
+ | * [{{SVN|vitalif/trunk/scripts/mcskin-vitalif-black.ini|markup}} Чёрный фон]. | ||
+ | * [{{SVN|vitalif/trunk/scripts/mcskin-vitalif-redblack.ini|markup}} Чёрный фон, красные менюшки]. | ||
+ | |||
+ | MC < 4.7.0, прописывать в mc.ini: | ||
+ | |||
+ | * [{{SVN|vitalif/trunk/scripts/mc.color|markup}} Чёрный фон]. | ||
+ | * [{{SVN|vitalif/trunk/scripts/mc-for-production.color|markup}} Чёрный фон, красные менюшки]. | ||
+ | |||
+ | == Syntax == | ||
+ | |||
+ | Описания синтаксиса для Midnight Commander. | ||
+ | |||
+ | * [{{SVN|vitalif/trunk/scripts/Syntax}} Syntax] | ||
+ | * [{{SVN|vitalif/trunk/scripts/tt.syntax}} tt.syntax] — синтаксис шаблонов {{CPAN|Template::Toolkit}}. | ||
+ | * [{{SVN|vitalif/trunk/scripts/tpl.syntax}} tpl.syntax] — синтаксис шаблонов [[Шаблонизатор VMX::Template|VMX::Template]]. | ||
+ | * [{{SVN|vitalif/trunk/scripts/perl.syntax.patch}} патч для perl.syntax] — исправленный синтаксис для Perl кода. | ||
+ | |||
+ | == Патчи == | ||
+ | |||
+ | Есть кучка патчей для различного софта — от Apache Tika до старой версии fglrx. Все они называются <tt>patch-***.diff</tt>. | ||
+ | |||
+ | Пример: gamin2.pl и патч Sys::Gamin. | ||
+ | |||
+ | Похож на [[#gamin.pl|gamin.pl]], но а) рассчитан на [{{SVN|vitalif/trunk/scripts/patch-Sys-Gamin-0.1-userData.diff}} патченую] версию Sys::Gamin 0.2, с поддержкой userData, и б) сильно менее полезен. | ||
+ | |||
+ | ./gamin2.pl /directory1 /directory/2 -u UserData2 some.file | ||
+ | |||
+ | Со всеми событиями от /directory/2 вы будете получать свои данные UserData2. | ||
+ | |||
+ | * [{{SVN|vitalif/trunk/scripts/patch-Sys-Gamin-0.1-userData.diff}} Патч к Sys::Gamin 0.1], добавляющий поддержку userData | ||
+ | * [{{SVN|vitalif/trunk/scripts/gamin2.pl|markup}} gamin2.pl] |
Текущая версия на 14:14, 27 февраля 2015
По адресу ~/s я поддерживаю некоторое количество простеньких полезных скриптов для решения различных задачек.
На данной странице описаны наиболее применимые из них, остальные можно увидеть по ссылке.
Содержание
Демоны
Демоны и около-демонические скрипты.
rsync-timemachine.pl
Инкрементальные (на файловом уровне) бэкапы (типа «Time Machine») на основе rupedia:Rsync, для любой unix-машины :) с небольшой дополнительной плюшкой — на Debian/Ubuntu дистрибутивах дампит и бэкапит MySQL-базы данных.
По месту назначения создаёт папочки с именами вида YYYY-MM-DD, названные в честь даты очередного бэкапа (текущей на момент запуска скрипта), и туда rsync’ом заливаются заданные директории.
А теперь Killer-Feature: используется опция --link-dest относительно последнего бэкапа, и они становятся инкрементальными! С этой опцией rsync сравнивает файл с предыдущей версией, и если он не менялся, создаёт жёсткую ссылку на неё. Таким образом дублирование файлов убирается на уровне ФС.
Чрезмерно старые бэкапы скрипт тоже удаляет сам — для этого ему нужно задать максимальный возраст бэкапа в днях. Всё, что старее, будет удаляться. Директории с именами, не равными дате в формате YYYY-MM-DD, скрипт не трогает, правда, если YYYY-MM-DD нет вообще, то бэкап будет сделан относительно не-YYYY-MM-DD-каталога.
На регулярность бэкапов скрипту пофигу — когда вызовешь, тогда и будет сделан очередной бэкап. Соответственно, задаётся регулярность просто включением скрипта в cron с нужным интервалом. Двойного одновременного запуска можно не бояться — скрипт отслеживает и его, с помощью pid-файла.
Синтаксис запуска: perl rsync-timemachine.pl -s МЕСТО_НАЗНАЧЕНИЯ [-A 'ОПЦИИ_RSYNC'] [-k ВОЗРАСТ] [-p PID-ФАЙЛ] [-D ПРОПУСТИТЬ_БД] ДИРЕКТОРИИ...
- МЕСТО_НАЗНАЧЕНИЯ в rsync’овском синтаксисе.
- ОПЦИИ_RSYNC — опции, которые нужно передавать во все вызовы rsync (например, --password-file=/etc/rsync.secret).
- ВОЗРАСТ — максимальный возраст бэкапа в днях. Если опцию не передавать — скрипт ничего не удаляет.
- PID-ФАЙЛ — даёт возможность (не шибко нужную, но мало ли) переопределить расположение pid-файла, равное по умолчанию /var/run/timemachine.pid.
- ДИРЕКТОРИИ — собственно, что бэкапим. Бэкапятся без полного пути, то есть например /var/backups/mysql попадёт по адресу МЕСТО_НАЗНАЧЕНИЯ/YYYY-MM-DD/mysql.
- ПРОПУСТИТЬ_БД — задаёт регулярное выражение для исключения баз данных из дампа.
http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/rsync-timemachine.pl?view=markup
logautocommit.pl
Идея скрипта: простой автоматический версионный контроль конфигурации сервера. Большая часть конфигурации в UNIX-системах, как известно, находится в /etc, поэтому в первую очередь нужно версионировать содержимое /etc. Причём, не так важно, куда коммитить изменения — скорее всего, подойдёт локальный репозиторий любой системы управления версиями (скажем, Subversion), но важно, чтобы:
- Изменения записывались автоматически.
- Записывалось, кем внесено изменение — очень желательно сохранять IP-адрес удалённой сессии, потому что системным пользователем почти наверняка будет root.
- Файлы коммитились не сразу, а через промежуток времени, чтобы в процессе редактирования каждое нажатие F2 (сохранение) не добавляло по коммиту.
- Изменения, вносимые менеджером пакетов, не учитывались.
Итак, встречаем скрипт. Он использует auditd для отслеживания изменений файлов в /etc — это наиболее оптимально в терминах производительности. Посему первый шаг — установить и настроить auditd:
apt-get install auditd echo -w /etc/ -p wa >> /etc/audit/audit.rule # логгируем запись в /etc/ /etc/init.d/auditd reload
Второй шаг — создать файл /etc/logautocommit-log4perl.conf со следующим содержимым:
log4perl.logger.ConfAutoCommit = INFO, ConfAutoCommit log4perl.appender.ConfAutoCommit = Log::Log4perl::Appender::File log4perl.appender.ConfAutoCommit.filename = /var/log/audit/autocommit.log log4perl.appender.ConfAutoCommit.layout = PatternLayout log4perl.appender.ConfAutoCommit.layout.ConversionPattern = %d %5p %C:%L %m %n log4perl.appender.ConfAutoCommit.create_at_logtime = 1
Здесь /var/log/audit/autocommit.log — путь к логу самой коммитилки.
Третий шаг: создать репозиторий и рабочую копию, добавить в них конфиги, которые уже лежат в /etc, и которые уже менялись (по вкусу).
svnadmin create /root/svn-etc-repo svn co file:///root/svn-etc-repo /root/svn-etc # cp /etc/… /root/svn-etc svn add /root/svn-etc/* svn ci -m 'initial configs'
И, наконец, запустить logautocommit.pl и прописать его запуск в /etc/rc.local, с нужными аргументами.
Использование:
./logautocommit.pl [ОПЦИИ]
или
./logautocommit.pl /etc/logautocommit.conf
Здесь /etc/logautocommit.conf — конфиг скрипта, может содержать те же [ОПЦИИ], по одной на строку.
Опции:
Формат 1 | Формат 2 | Описание | По умолчанию |
---|---|---|---|
-a XXX | log=XXX | Путь к логу auditd | /var/log/audit/audit.log |
-d XXX | etcdir=XXX | Путь к версионируемой директории | /etc |
-w XXX | workdir=XXX | Путь к рабочей копии | /root/svn-etc |
-e XXX | exclude=XXX | Исключить изменения файлов с именами, подпадающими под регулярное выражение XXX | ^/etc/(alternatives|rc\d?\.d)|(^|/)(\.#|mtab|ld\.so\.cache|adjtime|motd$)|\.dpkg-(new|dist)$|\.default$|/\.svn/ |
-x XXX | exclude_exe=XXX | Исключить изменения, сделанные приложения с именами образа, подпадающими под регулярное выражение XXX | (^|/)dpkg$ |
-l XXX | log_config=XXX | Использовать файл XXX как конфиг для логгера Log::Log4perl | /etc/logautocommit-log4perl.conf |
-c XXX | chktime=XXX | Проверять изменения файлов через XXX секунд | 60 |
-m XXX | comtime=XXX | Коммитить не чаще, чем в XXX секунд | 300 |
-p XXX | polltime=XXX | Интервал спячки после прерванного блокировующего чтения | 0.5 |
-b | background=1 | Уйти в фоновый режим после запуска | Да |
-f | background=0 | Не уходить в фоновый режим, полезно для отладки | Нет |
- FIXME: проверить, как скрипт работает с символическими ссылками.
- FIXME: проверка того, что изменение сделано через dpkg, работает не до конца корректно и иногда коммитятся лишние файлы, не менявшиеся руками
Кроме содержимого /etc, полезно также версионировать списки установленных пакетов системного менеджера пакетов и скриптовых языков типа Perl, PHP, Python, Ruby — это проще всего сделать, добавив в крон скрипт со следующим содержимым:
COLUMNS=3000 dpkg -l > /etc/packages-status-debian perl -MCPAN -e "CPAN::Shell->r" > /etc/packages-status-perl pear list > /etc/packages-status-php gem list > /etc/packages-status-ruby
Для Python аналогично простой команды нет, но можно воспользоваться скриптом pkgsearch.py с данной страницы:
python pkgsearch.py > /etc/packages-status-python
Ещё может оказаться полезным версионировать схемы всех баз данных, но это уже частично относится к разработке.
FastPerl
Простой однопоточный FastCGI демон для запуска CGI-скриптов в FastCGI-среде без перекомпиляции и дополнительных телодвижений. Хорошо подходит, например, для запуска awstats.
Опции запуска:
- -h
- вывод справки;
- --verbose
- подробный вывод;
- --pid=PIDFILE
- установка пути в pid-файлу;
- -l=LOGFILE
- установка пути к файлу журнала;
- -S=UNIXSOCKET
- установка пути к UNIX-сокету, на котором оно будет слушать;
- -P=UNIXPORT
- установка TCP/IP-порта, на котором оно будет слушать и биндиться к 0.0.0.0 (ко всем интерфейсам);
- -r=REGEXP
- установка ограничений на SCRIPT_FILENAME. Если оно не удовлетворит регулярному выражению REGEXP, будет отдан ответ HTTP 403 Forbidden.
Init-скрипт прилагается, по умолчанию выполняется под пользователем www-data и группой www-data, логи в /var/log/fastperl.log, сокет в /var/run/fastperl.socket, PID-файл в /var/run/fastperl.pid, без ограничения. Init-скрипт понимает /etc/default/fastperl с переменными:
- USER=user: group
- LOGFILE=
- SOCKET=
- PIDFILE=
- RESTRICTION=
Для работы init-скрипта сам демон нужно класть как файл /usr/sbin/fastperl.
- fastperl.pl — сам демон.
- fastperl.init — /etc/init.d-скрипт для запуска FastPerl в Debian/Ubuntu системах.
- Основан на http://wiki.codemongers.com/NginxSimpleCGI.
gcauthcd.pl
Клиент для МиГ-Телекомовской авторизации (Gagarin-Club AUTHentication Client Daemon), переписанный на Perl’е. Исходников реального gcauthcd я не видел, данный сделан чисто исходя из тривиального реверс-инжиниринга. Сам его и использую использовал, по причине того, что SSL-сертификаты у них давно протухли, виндовый gcauthcd это не парит, а реальный линуксовый работать отказывается, а хакнуть и заставить его не получается по причине статической линковки.
Логин-пароль берёт либо из /etc/gcauth.passwd, либо из файла указанного ./gcauthcd.pl -c /path/to/password.file
, в формате «LOGIN:PASSWORD». Опция --fg даёт возможность не сворачивать его в background, --force — запускать при неработающей авторизации, время от времени открыть доступ он тогда всё равно будет пытаться.
gamin.pl
Пригодный для автоматизации скрипт для мониторинга изменений файлов и директорий с помощью модуля Sys::Gamin (использующего реализацию FAM’а (File Alternation Monitor) «libgamin») версии 0.1. События выводятся на STDOUT в две колонки, скрипт живёт, пока не прибьют сигналом. Первая — имя события (одно из: change, delete, start_exec, stop_exec, create, move, ack, exist, end_exist), вторая — имя файла. К имени события может быть дописаны суффиксы:
- «|D» = «путь является каталогом и запрошен нерекурсивный режим»
- «|M» = «запрошен рекурсивный режим, запускаю мониторинг каталога»
- «|C» = «путь удалён, отменяю мониторинг каталога»
Соответственно, скрипт можно использовать в каких-нибудь скриптах (шелл или не очень) как монитор ФС, читать и парсить его вывод, и действовать по ситуации.
Синтаксис вызова:
./gamin.pl [-n] /directory1 /directory/2 some.file
Опция «-n» означает «мониторить нерекурсивно».
bind9-forwarders-resolvconf
Скрипт для обновления forwarder’ов DNS-сервера bind при DHCP-обновлении набора доступных DNS. То есть, это скрипт для установки на машину-роутер, потому что, предположительно, только машина-роутер может иметь и внешний интерфейс, на котором работает DHCP, получающий обновления DNS провайдера, и bind, которому нужны корректные forwarder’ы.
Скрипт сильно похож на стандартный дебиановский /etc/resolvconf/update.d/bind и тоже предназначен для установки в /etc/resolvconf/update.d/, отличается от стандартного следующим:
- Написан на perl ⇒ не использует «особую уличную магию» с кучей вызовов sed и посему не глючит
- Берёт /etc/bind/named.conf.options.in, заменяет в нём $FORWARDERS на список обнаруженных DNS, разделённых точками с запятой (но без; в конце, то есть надо писать forwarders { $FORWARDERS; }) и записывает в /etc/bind/named.conf.options.
- Не дёргает без надобности (когда конфиги не менялись) rndc reconfig.
Команды
Простые полезные консольные команды, которых часто не хватает в UNIX-окружении.
cpshift.c
Простая C-программка для копирования кусков файлов. Нечто типа dd, но удобнее, потому что
- Не требует задавать смещения, кратные размеру буфера => простая задача «вытащить X байт из файла, начиная с Y» выполняется в ПИЦОТ раз быстрее, потому что используется большой буфер, а не dd bs=1.
- Поддерживает обратный порядок копирования => позволяет корректно перемещать данные внутри одного файла (например, разделы на диске!) ВПЕРЁД. Если имя входного файла равно имени выходного, то сама выбирает нужный порядок — вперёд или назад — по разнице смещений.
- Поддерживает отрицательные входные смещение и размер — тогда, как в substr в Perl/PHP, они считаются от конца входного файла.
- Понимает шестнадцатеричные и восьмеричные значения параметров — удобно, потому что не нужно обрамлять их в $(()) или конвертировать в десятичные значения.
- Печатает прогресс копирования в %.
Короче, может быть, оно и велосипед, но с первого взгляда я такой стандартной unix-тулы не нашёл, а dd, простите, дебилен.
Компилировать тривиально:
gcc -o cpshift cpshift.c
Использовать тоже просто, вот только опций поприбавилось :)
./cpshift [OPTIONS] infile [outfile]
- Копирует кусок файла 'infile' в 'outfile'.
- 'infile' может быть равен 'outfile', тогда данные перемещаются в одном файле.
- Никогда не обрезает длину выходного файла.
- Если 'outfile' не задан или равен '-', то данные копируются на STDOUT. 'infile' также может быть '-', в этом случае данные копируются из STDIN. Однако, эти потоки всё равно должны поддерживать позиционирование, что cpshift с ними работал.
- Все численные параметры могут быть десятичными (например, 256), шестнадцатеричными (0x1AB) или восьмеричными (0127).
Опции:
- --skip SKIP_BYTES — смещение от начала входного файла в байтах. Может быть отрицательным, и тогда считается от конца входного файла.
- --size SIZE_BYTES — максимальный размер копируемой области в байтах. Может быть отрицательным, и тогда копируется всё до позиции (размер_файла-SIZE_BYTES).
- --skip-output SKIP_IN_OUTPUT — смещение в выходном файле в байтах.
- --buffer BUFFER_SIZE — размер буфера (сколько байт копировать за раз). По умолчанию 1 Мб (0x100000 байт).
- --reverse — задаёт обратный порядок копирования. В принципе, опция нужна редко, так как если входной файл равен выходному, то нужный порядок выбирается на основе смещений автоматически.
English help
./cpshift [OPTIONS] infile [outfile]
- Copies part of 'infile' to 'outfile'.
- Never truncates the output file.
- 'infile' can be equal to 'outfile', then data is moved within one file.
- All numeric parameters may be decimal (256), hexadecimal (0x1AB) or octal (0127).
- '-' can be specified as 'infile' (means STDIN) or 'outfile' (means STDOUT). Note that it must be anyway seekable for cpshift to work with it.
Options:
- --skip SKIP_BYTES — skip to this position inside the input file. SKIP_BYTES can be negative; if so, it is counted from the end of input file.
- --size SIZE_BYTES — copy at most this count of bytes. SIZE_BYTES can be negative; if so, it means copy up to the (-SIZE_BYTES)'th byte from the end of input file.
- --skip-output SKIP_IN_OUTPUT — skip to this position inside the output file.
- --buffer BUFFER_SIZE — copy this count of bytes at once (default 1 MB = 0x100000 bytes).
- --reverse — use reverse copying order. In most cases you don’t need to set this manually because when you’re moving data within one file, the correct copying order is selected automatically based on offsets (reverse order is used when moving data forward, forward order is used when moving data backward).
move-mdadm0.9.c
Простая утилита для перемещения mdadm’овского суперблока при изменении размера RAID-разделов. Лицензия: GNU GPL 3.0 или более поздняя, в том виде, в котором опубликована Фондом Свободного Программного Обеспечения.
Компиляция и использование:
gcc -o move-mdadm0.9 move-mdadm0.9.c ./move-mdadm0.9 device old_size_in_bytes new_size_in_bytes
Есть несколько версий суперблока mdadm — 0.90, 1.0, 1.1 и 1.2. Версии 1.1 и 1.2 располагаются в начале дискового раздела и поэтому не нуждаются в перемещении при изменении его размера; версии 0.90 и 1.0 суперблока, однако, располагаются в конце раздела и поэтому при изменении размера раздела их нужно перемещать.
Стандартный подход для этого — удалять диски из массива по одному, изменять их размер и добавлять обратно, опять-таки по одному. Это долго, так как требует синхронизации данных (resync) после добавления каждого диска. Только после завершения нескольких resync вы сможете запустить mdadm --grow.
Чтобы этого не делать и была написана данная утилита. С ней вы можете просто остановить массив (mdadm --stop), изменить размеры всех разделов, запустить ./move-mdadm0.9 <раздел> <старый_размер_в_байтах> <новый_размер_в_байтах> на каждом разделе и запустить массив обратно, после чего он будет сразу готов для выполнения команды mdadm --grow.
English help
Simple tool that allows to move mdadm v0.90 and v1.0 superblocks after resizing a device. License: GNU GPL 3.0 or later, as published by the Free Software Foundation.
Compiling and usage:
gcc -o move-mdadm0.9 move-mdadm0.9.c ./move-mdadm0.9 device old_size_in_bytes new_size_in_bytes
mdadm superblock is the metadata structure stored on devices/partitions participating in a software raid array. There are several versions of metadata format, namely v0.90, v1.0, v1.1 and v1.2. v1.1 and v1.2 superblocks are stored in the beginning and thus do not need moving when the raid partition is resized. However, v0.90 and v1.0 superblocks are stored in the end of the partition, so they need to be moved during resize, or mdadm won’t be able to find them.
The standard approach is to remove, resize and re-add disks from the array one by one, but it requires a resync after re-adding each disk, which takes a long time and is basically redundant. Only after all resyncs, you’ll be able to run mdadm --grow.
With this tool, you can just stop the array, resize all partitions, run ./move-mdadm0.9 <device> <old_device_size_in_bytes> <new_device_size_in_bytes> on each of them, start the array again and it will be immediately ready for mdadm --grow.
bindiff.c
Побайтно сравнивает два файла и печатает разницу между ними в шестнадцатеричном виде, в формате «адрес: старые_данные новые_данные» (точно такой формат использовался для патчей телефонов Siemens программой V_KLay):
00C01582: 0145 0000 00C01587: 02 00 ...
Компилировать просто — gcc -o bindiff bindiff.c. Использовать так — ./bindiff file1 file2.
fromto
Скрипт для перекодирования файлов из одной кодировки в другую. Использовать очень просто:
~/s/fromto cp1251 utf-8 файл1 файл2 ...
Поддерживает все кодировки, понимаемые Perl модулем Encode.
intdu, intsort
«Интерактивный» консольный sort — не ждёт полного результата, а показывает последние LINES строк, обновляющиеся по каждой строке, полученной со стандартного ввода (LINES = `tput lines` = число строк в текущем окне терминала). Строки, «уходящие» назад за пределы окна терминала, отсортированными не являются и смотреть их не надо.
Применение: команда «intdu», интерактивно подсчитывающая размеры подпапок текущего каталога и показывающая вам LINES самых больших папок.
- http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/intdu?view=markup
- http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/intsort?view=markup
whichpm
Аналог which для Perl-модулей — говорит, где лежит тот или иной модуль.
$ ~/s/whichpm Encode /usr/lib/perl/5.10/Encode.pm
unzip.pl
Используйте вместо стандартного unzip — после разархивации перекодирует кривые имена файлов, бывших русскими внутри архива.
convert-filenames
Скрипт для перекодирования имён файлов в каталоге из одной кодировки в другую. Сам ничего не выполняет, только выводит на STDOUT список команд mv A B. Пример использования:
./convert-filenames /path/ cp1251 koi8-r | sh
timestamp
Простая утилита преобразования дат для тех, кто привык к коду MediaWiki (wfTimestamp()).
./timestamp <желаемый_формат_даты> <дата>
На входе дата в любом из желаемых форматов. Единственное замечание — чтобы корректно парсить даты в формате TS_MW, нужно передавать их с пробелом в начале, типа ./timestamp TS_UNIX ' 20100101000000', чтобы «сплошное число» можно было отличить от UNIX времени.
Форматы даты/времени поддерживаются следующие:
- TS_UNIX
- UNIX время (число секунд с 01.01.1970).
- TS_DB
- YYYY-MM-DD HH:MM:SS.
- TS_DB_DATE
- YYYY-MM-DD.
- TS_MW
- YYYYMMDDHHMMSS.
- TS_ISO_8601
- YYYY-MM-DDTHH:MM:SS.
- TS_EXIF
- YYYY:MM:DD HH:MM:SS.
- TS_RFC822
- Wday, DD Mon YYYY HH:MM:SS +ZZZZ. Wday — 3-буквенная латинская аббревиатура дня недели, Mon — 3-буквенная латинская аббревиатура месяца, ZZZZ — зона, смещение от GMT в формате HHMM (часы, минуты).
- TS_ORACLE
- DD-Mon-YYYY HH.MM.SS AM|PM.
convert-many
Скрипт для перекодирования множества изображений из одного формата в другой с помощью GraphicsMagick или ImageMagick, возможно, в несколько потоков. Пример использования:
find /path/ -name *.png | xargs ./convert-many png jpg 2 | sh
bashrc.any
Команды для переключения кодировок koi8, utf8, cp1251 в KDE Konsole из консоли, не прибегая к помощи менюшек. Версии для KDE 4.x и 3.x.
А команда yc вам не нужна, удаляйте её. :)
Хелперы
Полезные инструменты для реализации какого-то однократного действия, слишком большие для того, чтобы называть их просто консольной командой.
calc-mem.pl
Подсчёт разделяемой и неразделяемой памяти, используемой процессами в Linux.
Скрипт предназначен для оценки требований памяти каких-нибудь форкающихся демонов типа apache2 httpd, php5-fpm и так далее.
Использование:
- ./calc-mem.pl -c php-fpm
- Разделить системные процессы на две группы — те, у которых команда запуска содержит регулярное выражение «php-fpm» и те, у которых не содержит, и вывести средние, суммарные и максимальные значения разделяемой и неразделяемой памяти по каждой группе.
- ./calc-mem.pl -p 1584
- Просто вывести разделяемую и неразделяемую память процесса с pid 1584.
Команды git
Хелперы для системы контроля версий git, написанные на чём попало. Они имеют имена вида «git-xxx» и если такой скрипт подложить в /usr/lib/git-core/, то «git xxx» вызовет этот скрипт.
git-ff
Типа git pull, но удобнее — автоматически делает Fast-Forward всем локальным веткам, связанным с удалёнными.
git-info
Выводит некую информацию о текущем репозитории, типа svn info.
git-sparse-checkout
Делает из обычной рабочей копии Sparse Checkout, то есть, сохраняет только заданные в командной строке пути, а остальные игнорирует.
git-truncate
Скрипт для кастрации истории git-репозитория. «git-truncate REV» угробит все ревизии старше REV и заменит их одной, включающей в себя состояние на момент REV. Дочерние ревизии REV будут пересажены наверх новой. Всё это, правда, произойдёт только в текущей ветке, другие ветки будут сохранены. Будет сохранена и предыдущая версия истории, если к ней ведёт путь от одной из других веток.
pgraph-dot
Скрипт для вывода графов зависимостей с использованием Graphviz веток патчей для расширения системы контроля версий Mercurial pbranch, служащего для автоматизированного управления множеством веток патчей.
Использовать в каталоге Mercurial-репозитория следующим образом: pgraph-dot имяфайла.формат, где формат — один из поддерживаемых Graphviz форматов вывода (png, svg, dot и т. п.)
Пример такого графа:
sgold-note.pl
Небольшой скрипт для извлечения заметок из файлов базы данных (0:/system/apo/note/) платформ Siemens SGold (x65/x75 кроме S75/SL75) и NewSGold (S75/SL75).
По умолчанию запускается для SGold. Чтобы запустить для NewSGold, нужно раскомментировать строчку #my $h = 4; # for NewSGold (убрать # в начале). Использовать, просто натравливая его на эти самые файлы — не на каталоги, а на сами файлы, ибо рекурсивно каталоги скрипт не обходит.
Персонализация
Патчи, модификации, файлы настроек, юзер-скрипты.
googletracking-b-gone.user.js
«Google Tracking B Gone» — скрипт отключает дебильные гугловские редиректы при кликах по ссылкам. То есть в поиске будут реальные ссылки на страницы, а не ссылки на гугловский URL, перенаправляющий на реальную страницу только после записи информации о вашем клике и мешающий копировать ссылки по правой кнопкею
Данная версия поддерживает как Firefox (Greasemonkey), так и Chrome с Opera, и постоянно используется мною в этих браузерах. Так что отсутствие глюков гарантировано.
В Opera для установки юзерскрипта надо создать любую папочку под свои юзер-скрипты, положить туда скачанный файл и прописать её в Preferences → Advanced → Content → JavaScript options → User JavaScript folder.
В Chrome — просто кликнуть «Скачать» и согласиться с установкой.
В Firefox — сначала поставить Greasemonkey, потом так же кликнуть «Скачать» и согласиться с установкой.
googlefocus.user.js
Ещё один пользовательский скрипт для гуглового поиска — на этот раз для тех, кого, как и меня, бесит то, что по умолчанию гугл при каждом нажатии любой буквенно-цифровой клавиши на клавиатуре автоматически фокусирует поле ввода. Данный скрипт отключает это поведение и, как и предыдущий, поддерживает Firefox/Chrome/Opera.
mc.color
Две цветовые схемы Midnight Commander: одна на чёрном фоне, вторая на чёрном фоне с красными менюшками, я её использую, чтобы сразу отличать боевые сервера от локальной машины.
MC >= 4.7.0, копировать в /usr/share/mc/skins, а в mc.ini прописывать skin=имя:
MC < 4.7.0, прописывать в mc.ini:
Syntax
Описания синтаксиса для Midnight Commander.
- Syntax
- tt.syntax — синтаксис шаблонов Template::Toolkit.
- tpl.syntax — синтаксис шаблонов Template|VMX::Template“Template|VMX::Template” не может быть использован как заголовок статьи на данном сайте..
- патч для perl.syntax — исправленный синтаксис для Perl кода.
Патчи
Есть кучка патчей для различного софта — от Apache Tika до старой версии fglrx. Все они называются patch-***.diff.
Пример: gamin2.pl и патч Sys::Gamin.
Похож на gamin.pl, но а) рассчитан на патченую версию Sys::Gamin 0.2, с поддержкой userData, и б) сильно менее полезен.
./gamin2.pl /directory1 /directory/2 -u UserData2 some.file
Со всеми событиями от /directory/2 вы будете получать свои данные UserData2.
- Патч к Sys::Gamin 0.1, добавляющий поддержку userData
- gamin2.pl