Tag Archives: linux
Настройка XDMCP, удаленного подключения к рабочему столу Linux
Не так давно я затрагивал вопрос настройки X11 Forwarding [Копия], что позволяет через ssh запускать отдельные графические приложения на удаленной Linux-машине (сервере). Теперь буду настраивать удаленный доступ к рабочему столу через XDMCP.
XDMCP внешне похож на RDP в Windows, т.е. при подключении пользователю будет предложено ввести логин и пароль в окне входа в систему и на экране отобразится удаленный рабочий стол. Фактически, на удаленной машине в памяти висит Display Manager (GDM, XDM и т.д.) и слушает 177 порт UDP, если от X-сервера с другой машины поступает запрос, Display Manager начинает с ним общаться, принимать оттуда изображение, а туда передавать координаты мыши и нажатия с клавиатуры, рисует окошко входа в систему. Если пользователь предоставил корректные данные для входа в систему, то он сможет работать с удаленным рабочим столом.
Внимание! Не все Display Manager’ы поддерживают работу по протоколу XDMCP. Точно поддерживают XDM, GDM, KDM и LightDM [3], так что проверьте в первую очередь, какой у вас Display Manager, и может ли он работать по XDMCP. Например, на одной из машин, к которой требовался доступ по XDMCP пришлось вместо LXDM ставить GDM.
Внимание! Протокол XDMCP довольно слабо защищен, так что его не рекомендуется использовать через Интернет без дополнительного шифрования. У нас, например, сделан доступ через VPN.
Первым делом необходимо открыть на файерволе нужные порты. Обязательно для входящих соединений открывается порт UDP 177. Если соединение планируется из Windows, то необходимо также открыть порты TCP 6000-6005 в обоих направлениях (входящие и исходящие соединения). Для соединения из Gnome вроде как надо открыть также в обоих направлениях порты TCP 16001 и 35091 [2]. На практике я проверял только подключение из Windows.
Команды для настройки файервола:
# XDMCP
echo "Open 177 port UDP (XDMCP) for Avallon AG clients..."
iptables -A INPUT -s x.x.x.x/yy -p udp --dport 177 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p udp --sport 177 -j ACCEPT
echo "Open 6000:6005 ports (Windows XDMCP) in both directions for AAG clients..."
iptables -A INPUT -s x.x.x.x/yy -p tcp -m multiport --dports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p tcp -m multiport --sports 6000:6005 -j ACCEPT
iptables -A INPUT -s x.x.x.x/yy -p tcp -m multiport --sports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p tcp -m multiport --dports 6000:6005 -j ACCEPT
Вместо x.x.x.x/yy
надо подставить адрес компьютера с которого будем связываться с компьютером под Linux, или маску подсети.
У меня был GDM, поэтому приведу его как основной, остальные дам для справки.
Необходимо найти файл custom.conf
, в источниках написано, что лежать он должен по адресу /etc/gdm/custom.conf
, но на самом деле это зависит от дистрибьютива. В моем случае файл находился здесь: /etc/X11/gdm/custom.conf
В файле, который выглядит, как обычный INI-файл необходимо найти секцию [xdmcp]
и вписать туда следующие параметры:
Enable=true
Port=177
Как видите, можно задать альтернативный порт для XDMCP.
Настройка других DM:
Под катом
Внимание! Стоит заметить, что в некоторых случаях конфигурационные файлы могут располагаться в других местах. Если их нет по указанным путям, можно воспользоваться поиском файлов в том же mc
Понадобится уже упомянутый в заметке про X11-Forwarding Xming.
Запускаем XLaunch и устанавливаем конфигурацию.
В первом окне выбираем один из режимов «одного окна», например One window, иначе не даст создать XDMCP сессию, и указываем номер дисплея 0 (обычно 0, если вы специально ничего не переопределяли на сервере, подробнее см. документацию по используемому Display Manager’у):
Описание настройки с иллюстрациями под катом
То при запуске Xming (через мастер XLaunch или с нужными параметрами) мы увидим окно авторизации в системе:

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

По клику доступно полноразмерное изображение
Чтобы каждый раз не вписывать и не выбирать вручную все параметры в мастере XLaunch, можно воспользоваться двумя способами:
1. Как ранее говорилось, сохранить конфигурацию в файл *.xlaunch
(например xdmcp.xlaunch
) и запускать мастер XLaunch, указывая ему с помощью ключа -load
файл конфигурации. Мастер XLaunch запустится, но все поля в окнах будут уже предварительно заполнены. Это удобно, если нужно соединяться по XDMCP с несколькими серверами, различающимися только, например, IP-адресом. Можно создать ярлык, в свойствах которого указать параметры к запуску XLaunch:
"C:\Program Files\Xming\XLaunch.exe" -load xdmcp.xlaunch

2. Создать ярлык Xming с нужными параметрами:
"C:\Program Files\Xming\Xming.exe" :0 -clipboard -query 10.10.3.24 -dpi 96
Естественно, вместо 10.10.3.24
нужно подставить свой адрес удаленной машины с XDMCP, а число после -dpi
выбрать под свои глаза и монитор.

1. Удаленный доступ по XDMCP (удаленное подключение к рабочему столу)
2.What Ports Need to be Opened for XDMCP
3.Xdmcp
Удаленная перезагрузка сервера под управлением Linux. Перезагрузка Linux без ввода пароля.
На самом деле делалось не для совсем сервера, но тем не менее. Стоит, в общем, на одном заводике в одной из стран СНГ аппарат по переработке пластиковых отходов в пластиковые полезности, управляет им комп с Linux на борту, а компом из будочки рядом управляет оператор с рабочего места с обыкновенной виндой. Комп с Линуксом надо иногда перезагружать, отключать, а в штатном ПО аппарата эту возможность почему-то не встроили. Раньше оператором был довольно умный парень, которому и root-пароль можно было доверить, и ssh, но он уволился, напоследок создав два батника примерно такого содержания:
plink -ssh -P 22 -l root -pw rutoviiparol 192.168.0.40 reboot
plink -ssh -P 22 -l root -pw rutoviiparol 192.168.0.40 poweroff
Бардак сущий, под root ходить для перезагрузки никуда не годится, да еще и хранить рутовый пароль в открытом виде. Можно, конечно, было бы подправить батник, сделав вход под юзерской учеткой, но sudo
было криво настроено и все равно оператору бы пришлось для перезагрузки вводить пароль.
Завести на сервере отдельных пользователей «для отключения» и «для перезагрузки» и настроить все так, чтобы при входе этих пользователей по ssh автоматически выполнялось выключение или перезагрузка, при этом не требовался ввод пароля, создать соответствующие bat-файлы на операторском рабочем месте.
Первым делом понадобится группа для этих пользователей. Самая простая операция. Назовем группу, например powermanager
и создадим ее (естественно, здесь и далее все команды, требующие root-доступа делаются из-под учетки root или через sudo
).
groupadd powermanager
В файле /etc/sudoers
как раз и описывается, какие пользователи и группы имеют возможность пользоваться утилитой sudo
, временно повышая свои права до root, и какие команды им разрешено выполнять без пароля.
Этот файл руками лучше не редактировать, а всегда делать это с помощью команды visudo
:
Файл настроек /etc/sudoers всегда следует редактировать с помощью команды visudo. visudo блокирует файл sudoers, сохраняет изменения во временный файл и проверяет, что файл грамматически корректен, перед тем как скопировать его в /etc/sudoers.
Важно:
Крайне важно, чтобы файл sudoers был без синтаксических ошибок! Любая ошибка делает sudo неработоспособным. Всегда редактируйте его только с помощью visudo для предотвращения ошибок. [1]
Но есть небольшая проблема, visudo,
в качестве вызываемого ей редактора, использует неудобный vi
, который без стакана и длительной практики может только «пищать и портить». Слава Ктулху, на компьютере стоял mc
, и, соответственно, mcedit
, поэтому:
1. Переопределение редактора для visudo
при однократном запуске:
EDITOR=mcedit visudo
Уфф, /etc/sudoers
открылся в человеческом mcedit
.
2. Постоянная замена редактора для visudo
Для этого добавляем в sudoers
следующие строки:
Defaults env_reset
Defaults editor=/usr/bin/mcedit, !env_editor
где editor=/usr/bin/mcedit
указание, какой редактор использовать
!env_editor
— запрет использования редактора, установленного переменными окружения (подробности смотрите по ссылке на детальное описание файла sudoers
в конце заметки).
Для разрешения пользоваться командой shutdown
без ввода пароля для пользователей группы powermanager
, в sudoers
следует добавить следующую конструкцию:
%powermanager ALL=NOPASSWD: /sbin/shutdown
Внимание! Для более полного понимания sudoers
настоятельно рекомендую ознакомиться со статьей по ссылке в конце заметки!
Внимание! Все пути в файле sudoers
должны быть полными
Пример файла sudoers
можно посмотреть здесь.
Создание пользователя для удаленной перезагрузки.
1. Создаем пользователя:
useradd -g powermanager -d /home/rebootusr -s /home/rebootusr/reboot.sh rebootusr
где:
-g powermanager
группа пользователя (ранее созданная powermanager
)
-d /home/rebootusr
домашний каталог пользователя
-s /home/rebootusr/reboot.sh
— оболочка для пользователя. Обычно здесь прописывается /bin/sh, /bin/bash
для интерактивных пользователей, или /bin/false
для неинтерактивных, например пользователя FTP, но можно задать и собственный скрипт, команды которого будут выполнены при входе пользователя в систему.
2. Задаем пользователю пароль (иначе не сможем залогиниться по ssh):
passwd rebootusr
3. Создаем домашний каталог:
mkdir /home/rebootusr
4. Меняем владельца каталога на пользователя rebootusr
chown rebootusr:powermanager /home/rebootusr
5. Меняем права доступа на каталог:
chmod 500 /home/rebootusr
6. Создаем в домашнем каталоге скрипт reboot.sh
со следующим содержимым:
#!/bin/sh
echo "Rebooting..."
sudo /sbin/shutdown -r now
где
-r
— указание программе shutdown
выполнить перезагрузку
now
— указание временного интервала — немедленно (можно еще выставить число в минутах, тогда перезагрузка произойдет через указанное время)
7. Меняем владельца и права доступа для скрипта reboot.sh
chown rebootusr:powermanager /home/rebootusr/reboot.sh
chmod 500 /home/rebootusr/reboot.sh
Аналогично создаем пользователя для выключения, меняя только имя, пароль, домашний каталог, название скрипта и команды в скрипте.
Содержимое скрипта для отключения питания poweroff.sh
:
#!/bin/sh
echo "Power off"
sudo /sbin/shutdown -hP now
Для Windows понадобится утилита plink
, обычно она идет вместе с ssh-клиентом PuTTY. В каталоге с ней создаем два bat-файла следующего содержания.
rebootsrv.bat:
plink -ssh -P 22 -l rebootusr -pw rebootpass 192.168.0.40
pwroffsrv.bat:
plink -ssh -P 22 -l pwroffusr -pw pwroffpass 192.168.0.40
где вместо rebootusr
и pwroffusr
надо подставить имена пользователей для удаленной перезагрузки и отключения питания соответственно, вместо rebootpass
и pwroffpass
— заданные пароли, а вместо 192.168.0.40
настоящий адрес удаленного компьютера.
1. sudo
[Копия]
2. Как перезагрузить компьютер без прав root [Копия]
Скрипт, разбирающий deb-пакеты
Понадобилось распаковывать deb-пакеты, чтобы вытащить из них некоторые программулины, для других версий Linux не собранные. Решил распаковку deb-пакетов автоматизировать и написать скрипт, распаковывающий, а точнее разбирающий на составные части все deb-пакеты, находящиеся в текущем каталоге.
Кратко и по рабоче-крестьянски, что такое deb-пакет. Фактически, это архив формата ar
, содержащий бинарные файлы программы, скрипты, необходимые пакетному менеджеру Debian для установки/удаления пакета и всякую служебную информацию, вроде контрольных сумм и прочего.
Нас интересуют бинарные файлы и неплохо бы посмотреть на предустановочные скрипты, ну мало ли чего там интересного и важного обнаружится. Установочные скрипты внутри архива ar
сжаты в архив control.tar.gz
, а вот бинарники находятся в архиве data.tar.??
, где вместо ??
может быть .gz, .xz
и т.д., в зависимости от того, что для сжатия бинарников было использовано. В архиве data
сохранена структура каталогов, идентичная каталогам в системе, куда будет установлен пакет, примерно как в пакетах Slackware (только структура каталогов, естественно, специфична для Debian-подобных Linux). В архиве control.tar.gz
могут содержаться скрипты конфигурирования, из которых наиболее интересны preinst
, выполняемый на Debian перед распаковкой пакета, и postinst
, выполняемый, когда пакетный менеджер распаковал бинарники в целевую систему. Естественно, просто так их выполнять не советую, но если делать из deb-пакета пакет Slackware, то не лишним будет с этими скриптами ознакомиться и буде там что нужное, передрать в doinst.sh
Определим основные переменные:
#!/bin/bash
DATADIR="./data" #директория, куда класть архивы с бинарниками
CONTROLDIR="./control" #... с управляющими скриптами
CURDIR="" #Текущая директория
Вывод краткой справки по использованию скрипта:
if [ "$1" == "-h" ]; then #print help echo "Unpacking all *.deb packages in current directory" echo "use" `basename "$0"` "[-c]" echo "-c - delete files in out-dirs" exit fi
Выводим информационное сообщение и создаем каталоги для хранения архивов с бинарниками и управляющими скриптами:
echo "Unpacking all *.deb packages in current directory"
echo "Making out-dirs... $DATADIR $CONTROLDIR"
mkdir $DATADIR
mkdir $CONTROLDIR
Если при запуске скрипта был указан ключ -c
, то очищаем содержимое директорий для хранения распакованных файлов:
if [ "$1" == "-c" ]; then echo "Clear out-dirs..." CURDIR=`pwd` cd $DATADIR rm * cd $CURDIR cd $CONTROLDIR rm * cd $CURDIR fi
С помощью команды find
получим список всех deb-пакетов (*.deb
) в текущей директории:
echo "Processing:"
F=`find . -name "*.deb" -type f`
где:
. (точка)
— указание команде find
искать в текущем каталоге.
-name
— после этого ключа задается нужная нам маска файла ("*.deb"
)
-type f
— искать только файлы (не каталоги, подпадающие под шаблон).
Результат отправляется (``
) в переменную $F
, которую обрабатываем в следующем цикле for
:
for FILE in $F
do
...
done
Что делаем в цикле:
Вызываем архиватор ar
с параметром t
, это выведет список файлов в архиве, потом при помощи grep
получаем имя архива data
с бинарниками (напомню, оно разное может быть, в зависимости от того, чем бинарники сжаты):
DATAPKG=`ar t ${FILE}|grep "data"`
Аналогично поступаем и с архивом control
, содержащим управляющие скрипты:
CONTROLPKG=`ar t ${FILE}|grep "control"`
Получаем имя deb-пакета без расширения (ключ -s ".deb"
команды basename
):
BASENAME=`basename -s ".deb" ${FILE}`
И расширения для содержащихся в deb-пакете архивов с бинарниками и скриптами:
EXTDATA=`echo $DATAPKG|sed 's/data//g'`
EXTCONTROL=`echo $CONTROLPKG|sed 's/control//g'`
echo "${FILE} : $DATAPKG, $CONTROLPKG"
Идея в том, чтобы при разборе пакета поименовать каждый архив также, каково имя пакета, присвоив правильное расширение, чтоб, если пакет не один, было понятно — какой архив от какого пакета, и чтоб они друг друга не затерли.
Вытаскиваем архивы из пакета:
ar -p "$BASENAME.deb" $DATAPKG > "$DATADIR/$BASENAME$EXTDATA"
ar -p "$BASENAME.deb" $CONTROLPKG > "$CONTROLDIR/$BASENAME$EXTCONTROL"
После запуска скрипта в каталоге, содержащем deb-пакеты, будкт созданы два подкаталога, содержащие архивы с бинарниками и архивы с инсталляционными скриптами.
Их уже можно распаковать стандартными tar’ом и gzip’ом или посмотреть их содержимое с помощью mc
На PasteBin
Скачать с Mega.nz
1. Архиватор ar
2. Структура deb-пакета
3. Цикл for
4. Распаковка пакета deb
5. basename --help
Универсальный конвертер символов перевода строки (Windows\Mac\Linux)
Ух и задолбался же я с этими самыми переводами строк! Возникла тут задачка конвертировать кучу огромную текстовых файлов из DOS/Windows (перенос строки CR+LF, h0D, h0A), старого Mac-формата (CR, h0D), который, вопреки утверждениям Википедии и других авторитетных источников использует не только вышедшие из употребления Маки, в формат Linux (LF, h0A). Желательно иметь возможность еще и обратной/произвольной конвертации между всем этим зоопарком. Сначала я, конечно, попробовал написать универсальный скрипт с помощью sed
, но никакой универсальности не получилось. На C++, ой, после C# это все равно, что пересесть с мерседеса на велосипед. На C# задача в строчки 4 кода решается, но тащить ради маленькой утилиты Mono, это уж слишком
В общем нашел готовую крохотную утилиту flip
.
Плюсы:
+ Есть готовые версии почти под все платформы, кроме DOS, даже статически откомпилированный бинарник для Linux, так что можно задуть в роутер/initrd, если оно кому-то там надо.
+ Бесплатно
+ Есть исходники
+ Работает моментально
+ Поддерживает файлы с перепутанными концами строк (где есть и Windows, и UNIX и Mac варианты)
Минусов пока не нашел.
Использование простое: первый параметр, что конкретно делаем, остальные — имена файлов через пробел.
Делать можно следующее:
-t
— отобразить используемый тип переноса строки
-d
— конвертировать в DOS/Windows формат (CR+LF)
-m
— конвертировать в Mac-формат (CR)
-u
— конвертировать в UNIX/Linux формат (LF)
Скачать можно со странички автора или отсюда:
1. Исходник
2. Slackware-пакет
3. Версия для Windows (консольная)
4. Все остальное
Няшная панель Qtpanel для Openbox и других WM для Linux
Недавно нашел няшную чОрную панель с меню Пуск для всяких там WM, у меня стояла на Openbox, но скрины будут с IceWM. Давно искал такую легковесную, простенькую и при этом няшную (чОрную, как мой кот) панель. Да, изначально была идея найти панель под цвет кота.
Правда, проект довольно старый и походу издох естественной смертью, но мне нравится.

Скрин из оригинальной статьи
А так она выглядит на терминальном сервере подшефной фирмы, куда я ее смеха ради и вас для задул на время:

По клику доступно
Может находиться и снизу:

По клику доступно
Статья и описание на Хабре
Скачать бинарный пакет для Slackware с Mega.nz
ЗЫ. Сборка: сообщество PuppyLinux Rus. Пакет для Slackware мой.
polkit-gnome-0.105 для Slackware x86 (i386)
Пост, скорее из серии, «чтоб не пролюбить, и самому потом долго не искать», чем конкретная детальная инструкция. Понадобился мне PolicyKit для GDM под x86 Slackware (14.1), из коробки его нифига не было, во всяком случае в нужном дистрибьютиве, пришлось собирать. Не буду детально описывать геморрой со сборкой, ибо зачем вам описание четырех кривых рук из двух стран, хехе. Наибольший геморрой случился с правильной сборкой требуемой ему библиотеки mozjs-17.0
, то ли я дурак, то ли оно изначально криво, но оригинал не собирался, ставился не туда, загаживал систему какими-то лишними файлами под 200 Мб, в общем тьфу и ужоснах. Совместными усилиями были найдены нужные слакбилды, так что тут краткая заметка для себя.
1. Собираем упомянутый mozjs-17.0 (aka js-185)
Sources
SlackBuild
Binary package (готовый собранный пакет) для x86 (i386) Slackware
2. Собираем polkit-0.133 (polkit-1)
Sources
SlackBuild
Binary package (готовый собранный пакет) для x86 (i386) Slackware
3. Наконец, собираем polkit-gnome (polkit-gnome-authentication-agent-1)
Sources
Binary package (готовый собранный пакет) для x86 (i386) Slackware
1 и 2 собираются стандартно
1. Распаковываем SlackBuild из архива в отдельный каталог.
2. Копируем туда архив с исходником.
3. Запускаем в этом каталоге ./Название_программы.SlackBuild Архив_с_исходниками.tar.gz
Финальный пакет замечательно соберется с помощью src2pkg
, если первые установлены.
Да, чуть не забыл, само дерево жужжать не будет, т.е. polkit-gnome-authentication-agent-1
автоматически не запустится, его надо прописать в какую-нибудь иксовую автозагрузку и после того, как стартуют иксы, GDM и будет сформировано окружение пользователя, т.е. или в скрипт Xsession
добавить строку /usr/libexec/polkit-gnome-authentication-agent-1 &
или добавить его в автозагрузку приложений, как описано, например, здесь
Позже я вернусь к описанию автозагрузки иксовых программ отдельно, во всяком случае опишу автозапуск в GDM и IceWM
Отключение автомонтирования USB-устройств при запуске X (gdm, icewm, spacefm)
Попросили разобраться тут с одной небольшой проблемой, при старте X-server’а и вообще графического окружения выполнялось ненужное, и даже вредное автоматическое монтирование USB-устройств. На подключенных к терминальному серверу флешках хранились ключи для бухгалтерии.
Проблема была в том, что подключающимся через XDMCP к графической оболочке пользователям, автоматически становились доступны подключенные к серверу носители USB.
Было известно, что графический интерфейс представляет собой связку GDM, IceWM в качестве desktop-manager’а и SpaceFM в качестве файлового менеджера. Исследование было недолгим, ибо такая конфигурация по умолчанию применяется в Absolute Linux, легковесном дистрибьютиве Slackware, который я же и посоветовал этой фирме года 3 назад 🙂
В автомонтировании был виновен SpaceFM, файловый менеджер. Поскольку, в самом менеджере все настраивается через графический интерфейс, и изменить настройки (локальные) может любой пользователь, то надо было искать другой выход.
Монтирование SpaceFM, естественно, осуществляет не сам, а использует udevil
. Соответственно, наиболее простое, быстрое и секурное решение — подправить конфиг udevil
. Выкладываю финальный параноидальный вариант, где udevil
запрещено монтировать все, что не было примонтировано до старта графической оболочки, и от любых пользователей (сменные носители, сетевые шары, оптические носители). Хотите монтировать — добро пожаловать в sudo
.
Конфиг: /etc/udevil/udevil.conf
Конфиг прекрасно документирован, правда на буржуйском, так что его можно переделать под свои нужды.
Скрипт для автоматического обновления паролей бесплатного VPN vpnbook.com
Как-то выкладывал конфигурационные файлы для PPTP-VPN от бесплатного VPN-сервиса http://vpnbook.com.
Правда у сервиса есть небольшой недостаток, как и у многих других бесплатных VPN, периодически меняется пароль. Благо, что пароль появляется у них на странице в текстовом виде, без всяких каптч, картинок и яваскрипта, и вполне просто автоматизировать его обновление, чтобы вручную не менять его в конфигурационных файлах после изменения на сайте.
VPNBOOKPAGE="http://www.vpnbook.com/#pptpvpn"
WORKDIR="/tmp/"
HTMLFILE="vpnhtml.txt"
PASSANCOR="Password:"
VPNBOOKPASS=""
FILEPASS=""
PEERSDIR="/etc/ppp/peers/"
PEERSFILES[0]="vpnbook-e214"
PEERSFILES[1]="vpnbook-e217"
PEERSFILES[2]="vpnbook-de233"
PEERSFILES[3]="vpnbook-us1"
PEERSFILES[4]="vpnbook-us2"
PEERSFILES[5]="vpnbook-ca1"
VPNBOOKPAGE
— адрес, по которому доступен текущий пароль.
WORKDIR
— рабочий каталог, куда будем сохранять полученную с сайта HTML-страницу с паролем
HTMLFILE
— имя сохраняемого файла
PASSANCOR
— Ключевое слово, по которому будем определять, где именно на странице пароль:

VPNBOOKPASS
— тут будем хранить пароль, полученный с сайта
FILEPASS
— тут будет пароль, сохраненный в данный момент в конфигурационном файле
PEERSDIR
— директория, в которой хранятся конфигурационные файлы для соединения с VPN-серверами vpnbook
PEERSFILES[0]...PEERSFILES[5]
— массив с именами конфигурационных файлов
I. Сначала, с помощью wget
, получим HTML-страницу, содержащую пароль.
echo "GET VPNBOOK PASSWORD v 0.2" #приветствие
rm $WORKDIR$HTMLFILE #удаляем текущий файл
echo "Get vpnbook page..."
wget -P $WORKDIR --default-page=$HTMLFILE --header="Content-type: text/plain" $VPNBOOKPAGE #сохраняем HTML-страницу
ВНИМАНИЕ! Существующий файл с сохраненной HTML-страницей надо обязательно удалить, иначе wget
при сохранении страницы добавит к имени дополнительно .1
(.2 .3
и т.д.).
Параметры утилиты wget
:
-P $WORKDIR
— установка рабочего каталога, указанного в переменной $WORKDIR
--default-page=$HTMLFILE
— установка имени файла, под которым в рабочем каталоге будет сохранена полученная с сайта HTML-страница. Имя указывается в переменной $HTMLFILE
--header="Content-type: text/plain"
— передаем серверу заголовок, в котором указываем, в каком виде хотим получить страницу (text/plain
). Лучше не упускать этот момент, одно время сервер почему-то отдавал без этого заголовка сжатую HTML-страницу, и анализировать ее потом было некузяво.
II. Проверяем, сохранилась ли страница:
if [ ! -f $WORKDIR$HTMLFILE ]; then echo "ERROR: Page not saved" exit 1 fi
III. Вытаскиваем пароль из сохраненного HTML-файла:
VPNBOOKPASS=`cat $WORKDIR$HTMLFILE|grep "$PASSANCOR"|head -n1|sed -e :a -e 's/<[^>]*>//g;/</N;//ba'|sed 's/.$//'|awk ' {print $2} '`
1. Выводим содержимое файла на stdout командой cat $WORKDIR$HTMLFILE
2. Передаем вывод команде grep
, она фильтрует строчку с содержимым, указанным в переменной $PASSANCOR
, т.е. строчку, содержащую слово "Password:"
и сам пароль. На самом деле команда grep
отфильтрует две строки, еще и с виндовыми концами строк:

3. Обрабатываем строчку дальше с помощью команды head -n1
Она получит из вывода команды grep
только первую строчку (-n1
)

4. Команда sed -e :a -e 's/<[^>]*>//g;/</N;//ba'
с вот этим диким регулярным выражением, удалит HTML-теги. Регулярка не моя, я нашел на просторах интернетов.

5. Следующая команда sed 's/.$//'
избавит строку от лишнего виндового символа конца строки.

6. Наконец, утилитой awk
, которая обрабатывает строки, воспринимая содержимое, как набор полей разделенных разделителем (по умолчанию пробел), вытаскиваем из строки непосредственно сам пароль. awk ' {print $2} '
Записываем результат в переменную VPNBOOKPASS
, обернув всю команду в обратные кавычки (``
)
Далее устанавливается размер массива, хранящего имена файлов настройки (специально так сделал, чтобы если добавится еще один файл конфигурации, количество обрабатываемых файлов обновлялось автоматически): CTR="${#PEERSFILES[*]}"
Далее инициализируется счетчик цикла I="0"
В цикле из массива извлекаются имена файлов, к ним добавляется путь к директории их содержащей, и эти данные передаются функции passwork
, которая получает пароль, сохраненный в файле конфигурации, и в случае необходимости его меняет на пароль, полученный с сайта.
until [ "$CTR" -eq "$I" ]; do passwork $PEERSDIR${PEERSFILES[I]} let "I+=1" done
Этим в скрипте занимается отдельная функция passwork()
, которой в качестве параметра передается полный путь к файлу конфигурации соединения. Вот ее код:
passwork() { echo -n "Checking $1..." if [ -e $1 ]; then #file exist COUNT=`cat $1|grep "password" -c` if [ $COUNT -eq 1 ]; then # strochek s parolem 1 #vitaskivaem password i udalyaem kavichki FILEPASS=`cat $1|grep "password"|awk ' {print $2} '|sed 's/\"//g'` echo -n "password "$FILEPASS if [ "$FILEPASS" = "$VPNBOOKPASS" ]; then #proverka parolya echo " not replaced." else #backup file cp $1 $1".bak" echo "...file backuped..." sed -i 's/'$FILEPASS'/'$VPNBOOKPASS'/g' $1 #replace password echo "...replaced!" fi else #>1 ili 0 echo " Peer file format error" fi else echo " $1 not found" fi }
В зарезервированной переменной $1
находится параметр, переданный функции из основной программы, в данном случае путь к файлу конфигурации соединения.
Сначала проверяется, существует ли файл:
...
if [ -e $1 ]; then #file exist
...
Если он существует, продолжаем работу, если нет — выводим сообщение об ошибке и выходим из функции:
...
else
echo " $1 not found"
fi
...
Сам конфигурационный файл выглядит так:
debug
#nodetach
unit 1
remotename ca1.vpnbook.com
ipparam vpnbook-ca1
pty "pptp ca1.vpnbook.com --nolaunchpppd"
name vpnbook
user vpnbook
password "wra2ezEz"
require-mppe-128
refuse-eap
noauth
file /etc/ppp/options.pptp
Далее получаем количество строк, содержащих конфигурационный параметр password
. Подсчет нужных строк можно выполнить командой grep
с ключом -c
COUNT=`cat $1|grep "password" -c`
Строк с параметром password
в конфигурационном файле должно быть строго 1, пароль заключается в кавычки.
Проверяем количество искомых строк:
...
if [ $COUNT -eq 1 ]; then # strochek s parolem 1
...
Если строка найдена, и она одна, то продолжаем работу, иначе выдаем сообщение об ошибке и выходим из функции:
...
else #>1 ili 0
echo " Peer file format error"
fi
...
Извлекаем содержащийся в конфигурационном файле пароль в переменную FILEPASS
:
FILEPASS=`cat $1|grep "password"|awk ' {print $2} '|sed 's/\"//g'`
1. Читаем файл с помощью команды cat
: cat $1
2. Отфильтровываем строку с паролем: grep "password"
3. Извлекаем пароль (в кавычках) с помощью awk
: awk ' {print $2} '
4. С помощью sed
удаляем кавычки: sed 's/\"//g'`
Далее сравниваем содержимое переменной FILEPASS
, т.е. пароль из обрабатываемого файла конфигурации, с паролем, полученным с сайта vpnbook. Он в переменной VPNBOOKPASS
.
...
if [ "$FILEPASS" = "$VPNBOOKPASS" ]; then #proverka parolya
…
Если пароли идентичны, то выдаем сообщение, что пароль не изменен. Иначе, делаем копию файла конфигурации (cp $1 $1".bak"
) и заменяем пароль с помощью sed
непосредственно в обрабатываемом файле (ключ -i
и указание пути к файлу в качестве последнего параметра команды):
sed -i 's/'$FILEPASS'/'$VPNBOOKPASS'/g' $1 #replace password
Попутно выводим сообщения о ходе процесса.
1. На PasteBin
2. Скачать с Mega.NZ
1. Команда head
2. Однострочные скрипты sed
3. Удаление кавычек с помощью sed
4. Краткое описание awk
[Скачать копии источников в формате PDF]
Заметка в формате PDF
Создание загрузочного образа диска DOS в Slackware Linux
Продолжая тему загрузочных образов.
Расскажу, как сделать загрузочный образ диска DOS в который можно добавить свои программы, загружаемый по сети или с CD-диска. На примере тестового образа, который использовал в одной из предыдущих заметок.
Загрузчик, соответственно, оставлю такой же, какой использовал ранее — SYSLINUX. Вообще SYSLINUX, а точнее memdisk
поддерживает кроме ISO загрузку образов дискет и жестких дисков, в т.ч. и сжатых gzip’ом.
С дискетами возникает небольшая проблема — файл образа должен быть строго определенного размера (хотя SYSLINUX поддерживает и нестандартные размеры дискет, но все равно они должны быть строго определенными), в образе дискеты, естественно, не может быть два логических раздела и т.д. Чтобы не заморачиваться с этими ограничениями, буду делать образ жесткого диска, его размер можно определить произвольно, главное, чтоб влез в память машины, на которой его потом будем загружать.
1. Устанавливаем простенькую виртуальную машину QEMU, для DOS ее вполне хватит.
2. Устанавливаем multipath tools, для того, чтобы получить доступ к файлам, расположенным в образе диска из Linux (ну если мы хотим добавить в образ какие-нибудь программы). У меня multipath tools были уже установлены, ибо нужны для работы с шифрованными контейнерами truecrypt/tcplay
Я установил необходимые программы с помощью менеджера sbopkg
без всяких дополнительных опций при сборке.
3. Если будем работать на удаленной машине через SSH, то настраиваем X11-forwarding
4. Создаем отдельный каталог в котором разместим необходимые образы дисков
5. Скачиваем выдранный из Hiren’s boot CD образ с досовыми утилитами. Или делаем его сами, как я описывал ранее
6. Проверяем, все ли работает, запускаем с досом, выдранным из HBCD:
qemu-system-i386 -cdrom dos.iso -boot d
где:
qemu-system-i386
— программа QEMU для 32-разрядных систем. В 64-разрядной версии Linux необходимо использовать команду qemu-system-x86_64
-cdrom
— указываем программе местонахождение ISO-образа диска (тут dos.iso
, расположенный в текущем каталоге).
-boot d
— указываем программе, что необходимо грузиться с виртуального CDROM’а (из указанного образа диска).
Должно получиться как-то так:


Во втором меню нужно выбрать пункт Next, далее File Managers и Volkov commander
Если Volkov Commander успешно загрузился, то закрываем QEMU и приступаем к созданию образа диска DOS
Первым делом создаем пустой файл (заполненный нолями) нужного размера, например 10 мегабайт. Делается это с помощью стандартной утилиты dd
dd if=/dev/zero of=diskc.img bs=10M count=1
Грузимся опять в QEMU с ISO-образа, но подключив созданный образ диска:
qemu-system-i386 -cdrom dos.iso -hda diskc.img -boot d
Выбираем в загрузочном меню HBCD Volkov Commander
Продолжение со множеством иллюстраций под катом
Готовый образ можно сжать gzip’ом, включить в состав загрузочного ISO-образа или загружать по сети. Пример конфига для ISOLINUX описан здесь
Как и что можно таким образом запускать:

Acronis Disk Director for DOS
Acronis True Image for DOS
Готовый образ диска
Заметку в формате PDF
Домашний FTP-сервер на Slackware и PureFTPd.
Когда-то давно поднимал вопрос создания простенького FTP-сервера для домашнего и мелкоофисного использования на Puppy Linux Slacko. Как-то незаметно настало время улучшить и углУбить мануал, и сделать такой же сервер, но на Slackware. Собственно программное обеспечение сервера решено оставить то же — PureFTPd. Ибо уже и какой-никакой опыт в настройке есть, и мануалов в сети много. Тут такая мини-инструкция, больше для себя, где я попытался воедино свести информацию из различных источников. К сожалению, не во всех все подробно описано, посему сперва столкнулся с некоторыми неочевидными глюками, и чтоб не гуглить потом все в разных местах, сам решил свести воедино все свои пометки в рабочем блокноте в данной заметке.
Сразу говорю, вопрос шифрования трафика, FTP через SSL в данной заметке благополучно упущен по причине ненадобности. Для общего доступа из Интернета данный сервер и не планировался, а для того, чтобы не бегать с флешками между десятком-другим компов, хранить бэкапы, дистрибьютивы софта, его как раз должно хватить.
Почему FTP, а не Samba? Не знаю, но FTP мне показался более простым в настройке, плюс универсальней — клиент FTP есть из коробки во всех «больших» ОС, начиная от Windows XP и кончая почти всеми Линуксами и MacOS, плюс FTP-клиент достаточно быстро прикручивается и к мобильным системам. Во всяком случае, подружить Android и iOS с FTP оказалось менее муторно, чем заставить нормально работать мобильные девайсы с расшаренными директориями в Samba на Linux, или с расшаренными папками в Windows.
/etc/shells
и проверяем в нем наличие строки /bin/false
Если ее нет — смело дописываем.Если данной строки нет, то при настройке могут проявиться всякие странные глюки. Например, на одном из дистрибьютивов пользователя для FTP-сервера удалось создать только с помощью скрипта-обертки
adduser
, а пользователи, созданные командой useradd
, почему-то получали отлуп при входе на FTP, несмотря на верное имя пользователя и пароль (и прочих верных параметрах). Хотя и adduser
(хоть и переспрашивая) и useradd
(ничего не спрашивая) позволяли отключить пользователю FTP оболочку, задав вместо нее /bin/false
. Так и не понял, какую магию добавлял скрипт-обертка, хотя параметры утилиты useradd
были идентичными
Примечание. Забегая вперед, скажу, что у PureFTPd есть замечательный механизм виртуальных пользователей. Он позволяет не плодить в системе кучу Linux-пользователей, которым нужно обеспечить доступ к FTP, а вместо этого создать всего одного, из-под которого будет работать сколь угодно виртуальных. Необходимые параметры виртуальным пользователям (имя, пароль, рабочий каталог FTP, объем выделенного дискового пространства, скорость закачки файлов) задаются с помощью утилиты pure-pw
, входящей в пакет PureFTPd, ею виртуальные пользователи также добавляются и удаляются.
ВАЖНО! Далее приводится инструкция по минимальной настройке FTP-сервера для дома или малого офиса. Настоятельно рекомендуется ознакомиться с полной версией инструкции к PureFTPd, если вы хотите открыть доступ к нему в Интернет и других общедоступных сетях, а также с инструкцией, как обеспечить работу FTP с шифрованием трафика (FTP через SSL).
Итак, приступим. Естественно, все делается через консоль под
root
1. Проверяем наличие строки /bin/false
в файле /etc/shells
2. Устанавливаем PureFTPd. Лично я установил его с помощью sbopkg, без дополнительных параметров при сборке пакета. Все заработало.
3. Создаем группу для пользователей FTP:
groupadd ftpgroup
где:
ftpgroup
— название группы для пользователей FTP, можете вместо ftpgroup
вписать любое уникальное название группы. Уникальное — значит, такой группы в системе не должно быть.
4. Создаем Linux- (системного, реального) пользователя для FTP. Этому пользователю для пущей безопасности (и корректной работы с виртуальными пользователями FTP) следует отключить командную оболочку и задать несуществующий домашний каталог. Добавляем нового пользователя в систему командой useradd
:
useradd -g ftpgroup -d /dev/null -s /bin/false ftpuser
где:
-g ftpgroup
— указывается группа пользователя, необходимо вместо ftpgroup
подставить ту, которую вы задали для пользователей FTP-сервера.
-d
— указание домашнего каталога, данному пользователю он не нужен, посему указываем /dev/null
— указание командной оболочки, используемой данным пользователем. Пользователь сам входить в систему не должен (и не будет для пущей безопасности), посему отключим ему доступ к командной оболочке, указав в данном параметре
-s/bin/false
ftpuser
— имя пользователя, можете выбрать любое по зову сердца, почек и печени.
Если что-то сделано неверно, всегда можно удалить пользователя в системе командой userdel имя_пользователя,
а группу командой groupdel название_группы
. Сведения об этих командах являются общими для всех дистрибьютьвов Линукс, кроме специальных, посему не буду останавливаться на них подробнее.
Сам демон FTP-сервера, будучи довольно универсальным для любых Linux- и даже Windows-based операционных систем сделан по принципу максимальной переносимости, посему он не признает as is конфигурационных файлов или конфигурационных каталогов. Для удобства пользователей разработчики (или сборщики) пакетов предусмотрели, что демон будет запускаться не напрямую, а через инициализационный скрипт, различный для конкретной ОС или ее дистрибьютива. Поэтому, если вы пользуетесь инициализационным скриптом, то способ конфигурирования будет различен для, например, Debian/Ubuntu или Slackware. Вы всегда можете обойти эти ограничения, запустив демон напрямую, и передав ему конфигурацию в соответствующих параметрах командной строки. НО в данной заметке такой способ не рассматривается, для управления (запуска, проверки статуса, остановки) демона, используется поставляемый в пакете для Slackware инициализационный скрипт, анализирующий соответствующий конфигурационный файл, разбирающий его и передающий конфигурацию демону.
Скрипт запуска: /etc/rc.d/rc.pure-ftpd
Его параметры: /etc/rc.d/rc.pure-ftpd start
запуск FTP-сервера
/etc/rc.d/rc.pure-ftpd stop
остановка FTP-сервера
/etc/rc.d/rc.pure-ftpd restart
перезапуск FTP-сервера
Файл конфигурации: /etc/pure-ftpd/pure-ftpd.conf
Можно много чего отконфигурировать, подключить базы MySQL или Постгресс, устроить аутентификацию через LDAP, установить квоты, но всего этого я делать не буду, если кому надо — конфигурационные файлы замечательно откомментированы, а подробных мануалов в сети есть. Комментарии в оригинале на буржуйской мове, но там даже ребенок через гугль-транслейт переведет. Я буду делать, повторяюсь, домашний сервер с виртуальными FTP-пользователями.
В файле конфигурации, раскомментируя соответствующие строчки, или заменяя yes
на no
(или наоборот), настраиваем следующие параметры:
#Не позволять пользователю выходить за пределы домашнего каталога
ChrootEveryone yes
#Отключить режим совместимости с "неправильными клиентами". Мне такие не попадались.
BrokenClientsCompatibility no
#запускать в режиме демона
Daemonize yes
#подробный LOG, можно поставить в no, если все работает, а FTP сильно загаживает логи
VerboseLog yes
#Анонимы дома не нужны (установка в yes включает полностью анонимный доступ к FTP)
AnonymousOnly no
#Отключаем возможность соединяться анонимно
NoAnonymous yes
#ОБЯЗАТЕЛЬНО раскомментируем эту строчку, задаем путь к базе данных виртуальных пользователей (можно путь не задавать, оставив, как есть)
PureDB /etc/pure-ftpd/pureftpd.pdb
#Обязательно комментируем эту строчку (или ставим соответствующее значение в no)
# PAMAuthentication yes
# и эту тоже комментируем, нефиг FTP соваться в системный файл аутентификации - пусть сам рулит виртуальными пользователями, которые специально для FTP
# UnixAuthentication yes
#автоматическое создание домашней директории для пользователя (при первом заходе на сервер)
CreateHomeDir yes
#использовать только IPv4, вряд ли в домашней или сети мелкого офиса нужен IPv6
IPV4Only yes
Готовый конфиг можно скачать здесь . Или посмотреть на PasteBin
Делается это следующей командой:
pure-pw useradd miguel -u ftpuser -g ftpgroup -d /home/ftp/files
где:
useradd
— команда добавления виртуального пользователя
miguel
— имя виртуального пользователя, будет использоваться FTP-клиентом для подключения к FTP-серверу. Естественно, можно придумать свое.
-u ftpuser
— реальный linux-пользователь, под которым будет работать данный виртуальный (см. выше).
-g ftpgroup
— группа пользователей FTP-сервера (см. выше)
-d /home/ftp/files
— директория для создаваемого виртуального пользователя. Если параметр CreateHomeDir
в конфигурационном файле сервера не закомментирован и установлен в yes
, то директория будет создана автоматически при первом входе данного пользователя через FTP-клиент.
После выполнения команды будет предложено ввести пароль для виртуального пользователя.
Можно создать неограниченное количество виртуальных пользователей, работающих из под одного реального с разными каталогами. Если установлен в yes
параметр ChrootEveryone
, то виртуальные пользователи не смогут перейти в каталоги других виртуальных пользователей, соответственно, мы можем наделать персональных директорий в FTP хоть для каждого устройства/конкретного пользователя, меняя только имена, пароли и домашние каталоги.
Примечание: Когда нужно дать доступ к одному и тому же каталогу нескольким пользователям, то просто в команде создания пользователя, после параметра -d
указывается одинаковый путь.
ВАЖНО! После любых изменений (добавления, удаления, смены пароля, и т.д.) виртуальных пользователей, необходимо выполнить команду обновления/создания базы виртуальных пользователей:
pure-pw mkdb
Иногда полезно иметь пользователя, способного только читать что-либо с FTP-сервера, но не имеющего возможности на него что-нибудь писать. Представим себе такую гипотетическую ситуацию, есть Миша, который завел себе домашний FTP-сервер, на нем виртуального пользователя под именем
miguel
, но к нему домой приходит множество друзей с ноутбуками, планшетами и прочими устройствами. На FTP-сервере хранятся фотографии Миши, но он не хочет, чтобы друзья пририсовали ему усы на этих фото. Как же быть?
1. Предположим, что пользователь для чтения-записи (в нашем случае miguel
) уже создан, и он уже совершил вход и загрузку хотя бы одного файла через FTP-клиент, соответственно каталог создан, и права на него уже установлены в 755, иначе потом вручную придется переставлять права.
2. Создаем второго реального пользователя в группе ftpgroup
:
useradd -g ftpgroup -d /dev/null -s /etc ftpuserread
3. Создаем виртуального пользователя, имеющего права только на чтение общего каталога с пользователем ftpuser
(и соответственно, с виртуальным пользователем miguel
, работающим в реальной системе из под соответствующего реального пользователя):
pure-pw useradd friends -u ftpuserread -g ftpgroup -d /home/ftp/files
4. После изменения виртуальных пользователей не забудьте выполнить команду
pure-pw mkdb
В процессе создания пользователя friends
можно задать для него пустой пароль, тогда получится псевдо-анонимный доступ. Друзьям можно дать имя пользователя, и они на FTP-сервер смогут войти без пароля (введя в своих FTP-клиентах пустую строку), а враги, гады, ведьма-соседка и рептилоиды из SCP будут долго подбирать имя пользователя, или же гоняться за всей вашей компанией с паяльниками. 🙂
Для смены пароля используем следующую последовательность команд:
pure-pw passwd miquel
pure-pw mkdb
где:
pure-pw passwd miquel
— команда смены пароля, вместо miquel
необходимо подставить имя нужного виртуального пользователя FTP, пароль будет предложено вести, символы не отображаются.
pure-pw mkdb
— обновляем базу данных.
pure-pw list
— список виртуальных пользователей
pure-pw show username
— подробная информация о пользователе, вместо username подставить существующее имя виртуального пользователя
pure-pw userdel username
— удаление виртуального пользователя, вместо username подставить существующее имя виртуального пользователя
Краткую инструкцию по командам можно получить, запустив утилиту управления пользователями (pure-pw
) с ключом --help
После каждой операции с виртуальными пользователями не забываем выполнить команду обновления базы:
pure-pw mkdb
1. Установка и настройка Pure-FTPD (Pure FTP) [Копия в PDF]
2. Официальный мануал PureFTPd
3. Slackbook
4. Не помню.
Настройка X11-forwarding через ssh, с помощью PuTTY и Xming
Вообще в Linux, а особенно на сервере под Linux вполне можно обходиться голой консолью, ибо все инструменты обычно в консольном варианте есть. Но иногда хочется запустить и графическое приложение, например программу разметки диска, а иногда без графики вообще не обойтись, если обрабатываешь видео или работаешь с виртуальными машинами. На наше счастье возможность удаленно работать с графическими программами есть. Называется это дело X11-Forwarding и существует оно аж в двух вариациях:
— XDMCP, нечто вроде RDP в винде — когда мы подключаемся к оконному менеджеру Linux, вводим свой логин/пароль и работаем с удаленным рабочим столом.
— И просто возможность запуска отдельных приложений (GIMP, GParted и т.д.)
К первому я еще может, когда-нибудь вернусь, а пока будем настраивать второе.
Будем считать, что ssh у нас уже настроен. Правим конфиг демона ssh
/etc/ssh/sshd_config
Раскомментируем или дописываем следующие строки:
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
Перезапускаем демон или рестартируем сервер.
Если надо, открываем порты на файерволе:
Для переопределения дисплея:
iptables -A INPUT -s x.x.x.x/xx -p tcp --dport 6000 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/xx -p tcp --sport 6000 -j ACCEPT
Вместо x.x.x.x/xx
подставить нужную подсеть
Щелкаем по значку в лотке, открываем Конфигурация и в появившемся окне выбираем в дереве слева Соединение -> SSH -> X11
Выставляем все значения как на картинке и запоминаем число после localhost:
(оно понадобится виндовому X-серверу).

Их, наверное с десяток всякоразных наберется, но я особо не экспериментировал, все побежали и я побежал, взял самый популярный Xming
1. Качаем с официального сайта или напрямую с SourceForge
2. Устанавливаем
3. Настраиваем, запускаем Пуск -> Все программы -> Xming ->XLaunch
Выбираем Multiple windows и устанавливаем Display number таким же, как было настроено в PuTTY:

Нажимаем Далее и выбираем Start no client, тогда Xming «поселится» в трее и будет ждать, пока мы с консоли PuTTY запустим какое-нибудь графическое приложение.

В следующем окне я оставил все также, поскольку Font Server не настраивал.

Хотя глюк со шрифтами у меня был, но как оказалось, его исправление особого шаманства не требует.
Если нажать Готово в следующем окне, Xming сядет в лоток и будет ждать, пока мы запустим что-нибудь графическое из консоли. Например
gparted &
символ &
— чтоб программа запустилась в фоновом режиме и не занимала консоль.
Чтобы каждый раз не лезть в XLaunch, можно в свойства ярлыка Xming дописать нужные параметры "C:\Program Files\Xming\Xming.exe" :0 -clipboard -multiwindow
По умолчанию Xming почему-то выставляет ОЧЕНЬ маленький размер шрифта меню и диалоговых окон

Борьба проста. Дописываем в окне Additional Parameters XLaunch’а в строку Additional parameters for Xming параметр -dpi 96 или его же в свойства ярлыка. Число в параметре выбираем под свои глаза и монитор

Вот что получилось:

Другие опции можно узнать из официального мануала
Источники не помню, но УМВР. И у друга тоже.
Выдираем досовую часть из Hiren’s Boot CD
Зело полезный набор утилит Hiren’s Boot CD за время своего существования уж как-то очень сильно раздулся, несмотря на то, что авторы в последних версиях повыкидывали оттуда всякую совсем уж проприетарщину, типа Windows 98, загружающейся с болванки. HBCD 15.2 весит целых 600 метров, что пофиг, если загружаешься непосредственно с болванки, и неприемлемо, если надо грузиться по сети на слабую машину со 128 метрами памяти, например. Но на такой машине весь HBCD и не нужен, а нужна только его досовая часть. Итак, выдираем ее и формируем отдельный образ.
Все дико просто, если пользоваться моей предыдущей инструкцией по ручной сборке образа загрузочного CD в Linux .
Итак, будем считать, что вы ее читали, и у вас уже подготовлена директория iso_root
, ней лежит минимальный набор файлов для загрузки (загрузчик ISOLINUX isolinux.bin
, его конфиг isolinux.cfg
, необходимые файлы *.C32
и memdisk
), а также скрипт вне директории iso_root
, который вызывает mkisofs
c нужными параметрами.
1. Создаем в директории iso_root
директорию HBCD
, а в ней директорию Dos
(все именно так, с сохранением регистра, иначе чуда может не получиться).
2. Вставляем в дисковод диск HBCD, и копируем все файлы из директории HBCD/Dos
в созданную директорию.
3. Выходим в директорию iso_root
и правим конфиг isolinux.cfg
, добавляя следующий пункт меню:
label dossoft menu label DOS Programs kernel memdisk initrd HBCD/Dos/dos.gz append floppy timeout 1000
4. Правим заголовок меню:
menu title DOS programs
5. Выходим на уровень выше и запускаем скрипт createiso
6. …
Образ готов! ФАНФАРЫ!

Загрузочное меню диска

Загрузочное меню досовой части Hiren’s Boot CD
Конечно, если попытаться загрузить Mini XP из этого меню или вернуться в основное меню HBCD, получим ошибку. Зато все досовые утилиты прекрасно работают (тестировано на «мониторе»). И весит этот образ всего 20 Мб, вместо 600 с гаком целого HBCD.
Готовый образ здесь
Как сделать загрузочный ISO-образ CD диска в Linux
Конечно, CD и DVD диски потихоньку выходят из обращения, но иногда еще нужны.
Сделать загрузочный образ диска в Linux очень просто.
1. В удобном месте создаем директорию iso_root
, в ней будут лежать все файлы, которые хотим поместить на загрузочный диск.
2. Копируем в директорию iso_root
нужные файлы.
3. Скачиваем загрузчик. Я воспользовался ISOLINUX из пакета загрузчиков SYSLINUX. Можно скачать нужную версию загрузчика вручную на https://www.kernel.org/pub/linux/utils/boot/syslinux, и распаковать полученный архив во временную папку, а можно воспользоваться готовым скриптом:
#!/bin/bash
SYSLINUXNAME="syslinux-4.02"
SYSLINUXADDR="https://www.kernel.org/pub/linux/utils/boot/syslinux/4.xx/$SYSLINUXNAME.tar.gz"
WORKDIR="/tmp"
cd $WORKDIR
wget $SYSLINUXADDR
tar -xf "$SYSLINUXNAME.tar.gz"
cd "$SYSLINUXNAME/"
Скрипт скачает нужную версию SYSLINUX (я использовал 4.02) в директорию /tmp
и распакует архив в каталог /tmp/syslinux-4.02
.
Весь загрузчик нам не понадобится, поэтому скопируем в директорию iso_root
только нужные файлы:
isolinux.bin
— собственно, загрузчик ISOLINUX
menu.c32
(или vesamenu.c32
) — файл, отображающий меню загрузочного диска, vesamenu.c32
если мы хотим сделать красивое графическое загрузочное меню
chain.c32
— утилита, передающая управление другим загрузчикам, например, загрузчику, расположенному на жестком диске.
reboot.c32
— утилита, перезагружающая компьютер, нужна, если мы хотим предусмотреть возможность перезагрузки из меню загрузочного диска.
memdisk
— программа, распаковывающая в память образы (в т.ч. и сжатые архиватором gzip
) жестких дисков, дискет.
Примечание: загрузчик SYSLINUX — операционная система в миниатюре, а файлы *.c32
— исполняемые загрузчиком программы.
4. Конфигурируем загрузчик и загрузочное меню. Загрузчик ISOLINUX ищет в том каталоге, в котором расположен, конфигурационный файл isolinux.cfg
, содержащий описание меню и конфигурацию загрузки.
Для примера я создал тестовый образ диска при заргузке с которого можно передать загрузку на первый жесткий диск компьютера, перезагрузить его или загрузить образ дискеты с DOS (позже расскажу для чего его делал и как). Содержимое конфигурационного файла isolinux.cfg
таково:
ui menu.c32 PROMPT 0 menu title Test disk label bootlocal menu label Boot From Hard Drive kernel chain.c32 append hd0 0 timeout 1000 label dos menu label Minimal DOS system kernel memdisk initrd dos/dos.gz append harddisk label reboot menu label Reboot Computer kernel reboot.c32
Команда ui menu.c32
вызывает обработчик меню, menu title
устанавливает его заголовок, далее идут описания пунктов загрузочного меню.
С label <имя>
начинается описание пункта меню, menu label
задает текст, выводимый в качестве пункта загрузочного меню. Команда kernel
дает команду загрузить ядро Linux или другое поддерживаемое ядро (в нашем случае memdisk
) или команду c32
, вместо команды kernel
можно использовать команду linux
, если загружать ядро Linux или C32
, если загружать специальную команду SYSLINUX. Команда initrd позволяет подгрузить образ начального диска Linux [ССЫЛКА] или образ диска или CD, загружаемый memdisk
‘ом. Команда append
передает ядру или команде дополнительные параметры. Команда timeout
устанавливает время, после которого будет автоматически выбран в случае бездействия пользователя соответствующий пункт меню. Число после timeout
задает время. За 1 единицу принята 0,1 с (соответственно, указанная в меню 1000 — 100 секунд).
5. Выходим из каталога iso_root
на уровень выше и cоздаем ISO-образ. ISO-образ создается программой mkisofs
где:
mkisofs -o disk.iso -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -J -R -V LABEL iso_root
-o
— задает имя образа диска (в примере disk.iso
)
-b
— имя загрузчика
-с
— задает имя загрузочного каталога, файл создается автоматически, формально не нужен, но лучше оставить.
-no-emul-boot
— Определяет, что используемый образ загрузки для создания загрузочного диска является образом без эмуляции. Система будет загружать и исполнять этот образ, не выполняя никаких операций по эмуляции диска. [1]
-boot-load-size количество_секторов
— Определяет номер «виртуальных» (по 512 байт) секторов для загрузки в режиме без эмуляции. По умолчанию загружается весь файл загрузки целиком. Некоторые BIOS могут воспринимать их с ошибкой, если их количество не будет кратно 4. (ИМХО, лучше 4 и оставить)
-J
— создает записи каталогов Joliet (см. мануал по ссылке в конце заметки, чтобы узнать, надо ли оно вам, но обычно рекомендуют указывать этот параметр).
-V
метка — задает метку тома
После параметров указывается имя каталога с содержимым CD-диска (iso_root
в примере).
Вот как выглядит меню диска, если с него загрузиться

Если надо создать несколько образов, процесс можно автоматизировать нехитрым скриптом. Метку тома можно указать в качестве первого параметра скрипта, иначе будет установлена метка bootable
На Pastebin
Скачать с Mega.nz
Готовый тестовый образ можно скачать отсюда
1. Перевод man mkisofs
2. ISOLINUX
3. SYSLINUX MEMDISK
Дожил до светлых дней!
Слава, блин, всем богам!
В новой версии Openvpn наконец по умолчанию и без пересборки работает опция получения пароля из текстового файла. Правда блядский Openvpn таки пришлось пересобирать с опцией ./configure --disable-plugin-auth-pam
, тому ще нет у меня этого самого pam и нафиг не нужно.
Ну и новая версия стала как-то стабильно работать, прошлая почему-то регулярно сегфолтилась.
Запускающий скрипт для tinyproxy
Ставил я не так давно простой и легкий прокси-сервер tinyproxy, и с удивлением не обнаружил в комплекте запускающего (инициализационного) скрипта.
Что это за зверь такой, если кто не знает. Ко многим демонам в Linux в комплекте идет инициализационный скрипт, позволяющий демона запустить, «убить» или перезапустить из консоли командой вида daemonname start (stop, restart)
без необходимости вручную отлавливать идентификатор процесса, убивать его командой kill
и проверять, завершен ли процесс (или наоборот, стартовал ли он). К squid
, например, такой скрипт идет, называется (в Slackware) rc.squid
и лежит в /etc/rc.d
, а к tinyproxy
в комплекте не шло, но написать его оказалось не так и сложно.
Итак, скрипт будет получать из командной строки единственный параметр с командой:
start
— запускать прокси-сервер
stop
— останавливать его
restart
— перезапускать (останавливать, а после остановки запускать)
status
— отображать, запущен или не запущен прокси.
#!/bin/bash
PIDFILE="/home/provproxy/tinyproxy.pid"
TINYPROXYCMD="/usr/sbin/tinyproxy"
PIDVAL=0
WTIMEOUT=30
OK=0
CH_S[0]='-' #pseudographic items
CH_S[1]='/'
CH_S[2]='|'
CH_S[3]='\'
ITEM_ARR=0 #current item counter
PIDFILE
— переменная, в которой указан PID-файл, файл, содержащий идентификатор основного процесса прокси-сервера. Tinyproxy
при запуске создает сразу несколько процессов, позволяющих ему распараллеливать свою внутреннюю работу. Минимальное и максимальное число таких процессов задается в конфигурационном файле /etc/tinyproxy.conf
параметрами MinSpareServers
и MaxSpareServers
, а процесс, идентификатор которого указан в PID-файле основной, управляющий. Ему можно послать сигнал, например, командой kill
, и все остальные процессы тоже завершатся. Местоположение PID-файла также указывается в файле /etc/tinyproxy.conf
в параметре PidFile
. Конечно, правильнее читать сам конфигурационный файл, и выдергивать значение параметра оттуда, ну да ладно, параметр этот перенастраивается нечасто, посему пусть такое решение останется на моей совести -=^_^-=.TINYPROXYCMD
— путь к исполняемому файлу прокси-сервераPIDVAL
— здесь будет храниться значение PID, полученное из PID-файла.WTIMEOUT
— максимальное время ожидания запуска tinyproxy
, или его завершения.OK
— флаг, принимающий значение 1 в случае успешного запуска/завершения, или 0 — в случае неуспеха. Вообще-то, можно и без него обойтись, но мне с ним удобнее и нагляднее.
CH_S[0] - CH_S[3]
, массив с псевдографическими элементами, для украшательства, отображения хода процесса запуска. Подробности про украшательства тут или тут , и если кому не надо, выбросить лишние команды из скрипта — дело нехитрое. Переменная ITEM_ARR
предназначена для тех же целей.
Далее, определим в скрипте несколько функций.
см. описание функций под катом
Проверять параметры будем при помощи оператора
case
, после объявления функций.
case "$1" in
start)
start_proxy
;;
stop)
stop_proxy
;;
restart)
restart_proxy
;;
status)
status_proxy
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
Если первый параметр, переданный из командной строки
start, stop, restart
или status
— выполняются соответствующие функции, если что-то еще (*
) — выводим краткую справку по использованию скрипта. В списке источников в конце заметки есть ссылка на более подробное описание оператора.
process_status()
. Вот ее код:
#Получаем PID
if [ -e $PIDFILE ];then #если файл существует
PIDVAL=`cat $PIDFILE` #читаем PID
TMPGREP=`ps -p $PIDVAL|grep "tinyproxy" -c` #процесс запущен - 1 иначе 0
if [ $TMPGREP -ge 1 ];then #процесс запущен
return #выходим из функции
else #pid-файл есть, процесса нет
rm $PIDFILE #удаляем pid-файл
fi
fi
PIDVAL=0
Сначала проверяется наличие PID-файла, если он существует, отправляем его содержимое (конструкция «), прочитанное с помощью команды
cat
в переменную PIDVAL
, далее, запрашиваем информацию о процессе (ps
) по его PID (ключ -p
). Если процесс существует, команда ps
отправит на стандартный вывод что-то типа:
PID TTY TIME CMD
2100 ? 00:00:00 tinyproxy
А если процесса не существует:
PID TTY TIME CMD
Далее, этот вывод передается команде grep
, которая фильтрует строки с именем искомого процесса (tinyproxy
) и подсчитывает их количество (ключ -c
). Если строк 1 процесс с данным PID существует, если 0 — процесса нет.
Если PID-файл существует, то в переменной $PIDVAL
остается идентификатор процесса и происходит выход из функции
[...] if [ $TMPGREP -ge 1 ];then #процесс запущен return #выходим из функции [...]
Если PID-файл существует, а процесс с данным PID не обнаружен, значит в PID-файле указан не тот PID, что, в большинстве случаев, может произойти из-за падения программы (с tinyproxy это случается довольно редко), либо из-за общего системного сбоя вызванного, например, отключением питания. Поэтому стоит PID-файл удалить.
Если процесс не обнаружен, или PID-файл не найден, то происходит выход из всех условных конструкций и переменной $PIDVAL
присваивается значение 0
[...]
PIDVAL=0
[...]
Таким образом, если процесс существует, то в переменной $PIDVAL
будет присутствовать его идентификатор, если не существует — значение 0.
Примечание о безопасности и стабильности использования PID-файлов. Конечно, есть более универсальный способ найти процесс не обращаясь к PID-файлу, например, получить список процессов командой ps ax
и отgrep’ать его, найдя нужное нам имя, и, если надо, то завершить его командой pkill имя_процесса
, и данный способ весьма неплохо будет работать с тем же tinyproxy
.
Но tinyproxy — это просто web-прокси сервер, и неизвестно, что произойдет, если применить такой метод, например, к серверу баз данных. Возможно, какие-то транзакции не завершатся, порушится сама база. Поэтому, информации, сохраняемой программами в PID-файлах, стоит доверять. Безопасность их использования и контроль доступа к ним других пользователей должны решаться другими средствами ОС. Посему я не вижу смысла загромождать скрипт дополнительными проверками.
За пояснение благодарю ketmar@ljr
Если функция
process_status()
используется для получения статуса (и PID) процесса для внутренних целей скрипта, то функция status_proxy()
выводит информацию пользователю. И хоть она очень проста, но лучше вынести ее отдельно, дабы не смешивать взаимодействие с пользователем со внутренней механикой программы.
Вот код этой функции:
status_proxy() { process_status if [ $PIDVAL -eq 0 ]; then echo "Tinyproxy not running" else echo "Tinyproxy running [PID=$PIDVAL]" fi }
Как я и говорил, функция очень проста, сначала вызывается функция process_status
, и если в переменной $PIDVAL
значение 0, то выводится сообщение о том, что tinyproxy не запущен, иначе, что запущен и дополнительно выводится его PID.
Выполняет его функция
start_proxy()
. Вот ее код:см. код и описание функции под катом
ПРИМЕЧАНИЕ: Если прокси не запускается, то для поиска неисправности удобно запустить прокси-сервер с ключом
-d
tinyproxy -d
В таком случае прокси запустится не в виде фонового процесса (демона), а в виде обычного, и выдаст ошибки на консоль. Например, если на файерволе закрыты порты, необходимые серверу, будет выведено сообщение:
tinyproxy: Could not create listening socket.
За остановку прокси-сервера отвечает функция
stop_proxy()
. Ее код:см. код и описание функции под катом
1. Запускаем функцию остановки
stop_proxy
.
2.
Сбрасываем флаг: $OK=0
Выполняем функцию запуска start_proxy
Вот нехитрый код функции restart_proxy()
:
restart_proxy()
{
stop_proxy
OK=0
start_proxy
}
С Pastebin
С Mega.nz
1.Bash. Функции.
2.Возврат значений из функции
3.Оператор
case
4.Tinyproxy
5.Коды завершения, имеющие предопределенный смысл
Конфиги pptp для vpnbook.com
Кое-кто просил pptp-конфиги для vpnbook.com
Получите, распишитесь.
На Pastebin:
Общий конфиг options.pptp
Куда класть, понятно из конфигов пиров (помещаются в директорию /etc/ppp/peers
)
vpnbook-ca1
vpnbook-de233
vpnbook-euro214
vpnbook-euro217
vpnbook-us1
vpnbook-us2
Скачать одним архивом с mega.nz
На euro-214 и 217 открыты все порты, на остальных доступен только HTTP/HTTPS, за торренты (ну так написано) могут типа по голове настучать, в смысле отрубить, но хз, я в принудительном режиме качал 100 метров, не отрубили.
217 на мой взгляд довольно падучий, 214 более стабильный, но чет последнее время тоже периодически разрывает коннект.
Сам пользуюсь в основном канадским, ну нравится мне, что сервер предоставляет моя любимая контора ZOG ЦРУ ФСБ СБУ CDC.
Конфиги не комментированные, гуглите, если что непонятно, как-нибудь может посвящу этому заметку, но не сейчас.
Можно закомментить строчку debug
, чтоб не срал лишнего в логи.
Пароль там действующий на момент публикации заметки, надо пердически менять, когда-нибудь затрону тему, расскажу, как автоматом менять, благо просто.
Решение проблемы отображения кириллицы в lynx
Собственно, некое продолжение темы из предыдущей заметки. Мне и потребовались русские буквы в консоли для того, чтобы вбивать их в строку поиска гугеля из консольного браузера lynx
. Так уж получилось, что был недавно в ситуации, где окромя консоли ничего нет, а почитать новости или Мракопедию хотелось. Или в гугель что-нибудь вбить.
Но lynx
с настройками по умолчанию подложил мне свинью, точнее маленького поросеночка. Русскоязычные сайты отображались translitom.

Оказалось, что лечится довольно просто (во всяком случае у меня)
1. Запускаем lynx на каком-нибудь сайте с русским текстом. Например lynx tolik-punkoff.com
2. Видим translit, но смело нажимаем кнопку «o» (латинская буква «о») и попадаем в окно с настройками браузера.
3. Пролистываем настройки (клавишами вверх/вниз) и становимся на пункт Display character set
в разделе Display and Character Set
, и видим там какую-нибудь фигню вроде Western (cp850)
4. Поднимаемся выше на пункт Use locale-based character set
, жмем Enter, в выпадающем списке выбираем On, жмем Enter
5. Поднимаемся вверх до пункта сохранения изменений (Accept Changes
) и жмем на нем Enter
Lynx сама определит кодировку, которую использует терминал, сохранит изменения на текущую сессию и перекинет нас обратно на сайт.
Если все получилось, значит, терминал русифицирован, и lynx
определил его кодировку

Если нет — скорее всего, косяк где-то в русификации консоли.
Осталось сохранить это на веки вечные. 🙂
Еще раз нажимаем кнопку «o», спускаемся на пункт Save options to disk: [ ]
, устанавливаем чекбокс нажатием на нем Enter и сохраняем изменения, как описывалось выше.
Можно ради интереса спуститься к пункту Display character set
и посмотреть, какую кодировку определил браузер. У меня, как и ожидалось, оказалась UNICODE (UTF-8)
Маленькая заметка по русификации консоли в Slackware
Понадобились мне русские буквы в чистой консоли. Решилось все на удивление просто.
Делается в файле
/etc/rc.d/rc.font
Его надо изменить так, чтобы подгружался нужный шрифт. Мне повезло, и шрифт, устраивающий меня, подгружался из коробки.
Но если шрифт не устраивает, то идем в /usr/share/kbd/consolefonts
и смотрим, какие там есть шрифты, соответственно изменяя /etc/rc.d/rc.font
по своему вкусу.
Например, шрифты у меня были такие:
LatArCyrHeb-19.psfu.gz
А сам
LatArCyrHeb-16.psfu.gz
LatArCyrHeb-14.psfu.gz
LatArCyrHeb-16+.psfu.gz
LatArCyrHeb-08.psfu.gz
rc.font
выглядел так:
#!/bin/sh
#
# This selects your default screen font from among the ones in
# /usr/share/kbd/consolefonts.
#
#setfont -v
setfont -v LatArCyrHeb-16.psfu.gz
Вроде все интуитивно понятно.
В файл
/etc/rc.d/rc.keymap
дописываем (или правим соответствующую по виду) строчку:/usr/bin/loadkeys /usr/share/kbd/keymaps/i386/qwerty/ruwin_ctrl-UTF-8.map.gz
Где самое интересное — файл
ruwin_ctrl-UTF-8.map.gz
В этом файле содержится описание раскладки клавиатуры и способа переключения.
Цитата из источника [2]:
Стоит прежде всего обратить внимание на ruwin под разные кодировки и варианты переключения:
$ (cd /usr/share/kbd/keymaps/i386/qwerty/; ls -1 ru*)
Конец цитаты
ru1.map.gz
ru2.map.gz
ru3.map.gz
ru4.map.gz
ru-cp1251.map.gz
ru.map.gz
ru-ms.map.gz
ruwin_alt-CP1251.map.gz
ruwin_alt-KOI8-R.map.gz
ruwin_alt-UTF-8.map.gz
ruwin_cplk-CP1251.map.gz
ruwin_cplk-KOI8-R.map.gz
ruwin_cplk-UTF-8.map.gz
ruwin_ctrl-CP1251.map.gz
ruwin_ctrl-KOI8-R.map.gz
ruwin_ctrl-UTF-8.map.gz
ruwin_ct_sh-CP1251.map.gz
ruwin_ct_sh-KOI8-R.map.gz
ruwin_ct_sh-UTF-8.map.gz
ru_win.map.gz
ru-yawerty.map.gz
На терминал, запускающийся из X, эти настройки не влияют, как и на PuTTY.
В PuTTY раскладка в консоли переключается аналогично раскладке во всем остальном Windows, а в иксах — соответственно настройкам иксов. Хотя на всякий случай я выбрал переключение левым Ctrl, которое отличается от моего виндового Ctrl+Shift, чисто на всякий случай, мало ли в PuTTY или еще где что поменяется, а я потом забуду где что менял.
1. Русификация Slackware 12
2. Русификация консоли в Slackware 14
Скрипт waiter, скрашиваем скучное ожидание в своих скриптах. Еще раз про обратный отсчет на BASH
Иногда бывает, что в скрипт надо вставить скучную команду sleep
, пока что-нибудь делается, например, поднимается сетевой интерфейс или стартует демон.
Вообще, правильнее в этих случаях писать отдельные проверки, проверяя в цикле, поднялось ли, запустилось ли нужное.
Но иногда лень и где некритично можно «просто подождать», как пелось у классика. А чтобы юзеру не было скучно, и он не думал, что наш скрипт висит, можно подменить обычный sleep
небольшим скриптом, показывающим обратный отсчет, да еще и с вращающейся псевдографической фенечкой.
Я уже когда-то поднимал этот вопрос, посему с ноля все делать не придется, нужно лишь чуть доработать имеющийся скрипт.
Итак, скрипту будут передаваться два параметра. Первый обязательный, содержащий время ожидания, и второй дополнительный — сообщение, выводимое в терминал. Если второй параметр не задан, то по умолчанию будет выдано сообщение, заранее определенное во внутренней переменной скрипта.
Определяем переменные (сообщение по умолчанию, время ожидания, счетчик текущего элемента в массиве псевдографической «мельницы» и сам массив элементов):
MESSAGE="Wait"
WTIMEOUT=0
ITEM_ARR=0 #current item counter
CH_S[0]='-' #pseudographic items
CH_S[1]='/'
CH_S[2]='|'
CH_S[3]='\'
print_help()
{
echo "use waiter <time> [message]"
echo "<time> - wait time"
echo "[message] - optional text message"
}
Проверяем первый параметр скрипта, на предмет того, нужно ли вывести справку и завершить работу:
#parameters check
if [ -z $1 ];then #if no parameters
print_help
exit 2
fi
#if help request
if [ $1 = "-h" ];then
print_help
exit 2
fi
if [ $1 = "--help" ];then
print_help
exit 2
fi
Проверяем первый параметр скрипта на соответствие его числовому значению (подробнее описано здесь):
if (echo $1 | grep -E -q "^?[0-9]+$");then
WTIMEOUT=$1
else
echo "Not a number in first parameter <time>"
exit 1
fi
И второй параметр. Если он не пустой, присваиваем его значение переменной, содержащей сообщение:
if [ -n "$2" ];then
MESSAGE=$2
fi
Переходим к основной части скрипта:
Выводим сообщение для пользователя и сохраняем позицию курсора:
echo -n $MESSAGE" ("$WTIMEOUT" secounds): "
tput sc #save cursor position
Ключ -n
в команде echo
означает, что следующее сообщение будет печататься на той же строке, команда echo
не совершит перевод курсора на следующую строку.
while [ $WTIMEOUT -ge 0 ]; do
#print timeout and current pseudographic char
printf '%3s %s' $WTIMEOUT ${CH_S[ITEM_ARR]}
tput rc #restore cursor position
sleep 1
#decrease timeout and increase current item ctr.
let "WTIMEOUT=WTIMEOUT-1"
let "ITEM_ARR=ITEM_ARR+1"
if [ $ITEM_ARR -eq 4 ];then
#if items ctr > number of array items
#starting with 0 item
let "ITEM_ARR=0"
fi
done
В рабочем цикле сначала выводим оставшееся время ожидания и текущий символ из массива псевдографических элементов, шаблон %3s
команды printf
означает, что если выводимая строка меньше 3 символов, недостающие с начала строки знаки заменяются пробелами, %s
, что просто выводим строку, как она есть. Далее указываются 2 переменных — оставшееся время ожидания и символ из массива.
Следующим шагом восстанавливаем позицию курсора (и все, что будет напечатано в следующей итерации цикла затрет предыдущие значения).
Далее ждем одну секунду и уменьшаем оставшееся время на 1, а счетчик текущего элемента массива увеличиваем и проверяем, не больше ли он, чем последний индекс в массиве. Если больше — присваиваем счетчику значение 0, в следующем цикле опять будет выведен нулевой элемент.
В завершении печатаем символ перехода на новую строку, чтобы следующие сообщения в следующих или в вызывающих этот скрипт скриптах начинались с новой строки
#next message starting with new string
printf '\n'