Бывает необходимо проверить состояние (статус) того или иного сетевого устройства, например, сетевой карты. Вообще вариантов может быть три:
1. Устройство работает (up)
2. Устройство есть, но не работает в данный момент (down)
3. Устройства нет вообще.
Описание принципа действия
Чтобы определить состояние сетевого устройства, нужно проанализировать вывод команды ifconfig. Если устройство вообще есть, то оно будет в выводе ifconfig -a (ключ -a — все устройства). Если устройство есть, но в данный момент не работает, в выводе ifconfig -a оно будет, в выводе ifconfig — нет.
Например, устройство veth1 в данный момент не работает, вывод ifconfig:
Значит достаточно отфильтровать вывод ifconfig и ifconfig -a grep‘ом по имени конкретного сетевого устройства, и заставить grep посчитать количество строк (ключ -c):
ifconfig -a | grep eth0 -c
eth0 — имя устройства.
Если количество строк будет 0 — устройства совсем нет.
ifconfig | grep $DEV -c
Если количество строк будет больше 0 — устройство работает (up), если предыдущая команда выдала 1, а эта команда нет, то устройство есть, но не работает (down). Если используются псевдонимы, то надо использовать полные имена (например, eth0:1).
Скрипт
Все это дело можно автоматизировать скриптом.
Продумаем коды возврата: 0 — сетевое устройство работает (up), 1 — устройство не работает (down), 2 — устройство не найдено (none), 3 — неправильные параметры скрипта или запрос справки.
Добавим в скрипт дополнительный параметр -s — если он указан, скрипт не будет выводить сообщений на консоль, а только сигнализировать о статусе сетевого устройства кодом возврата (для использования в других скриптах).
#!/bin/bash
#check network device status
#exit codes 0 - device up 1 - device down 2 - none device
#3 - help or wrong parameters
SLNT=0
print_help()
{
echo "Use "`basename $0`" [-s]"
echo " - network device name, e.g. eth0"
echo "-s - silent mode, no console output"
}
#parameters check and set silent mode
if [ $# -eq 0 ]; then
echo "Wrong parameters!"
echo
print_help
exit 3
else
if [ $# -eq 2 ]; then
if [[ "$2" == "-s" ]]; then
SLNT=1
else
echo "Wrong parameters!"
echo
print_help
exit 3
fi
fi
fi
#print help
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
print_help
exit 3
fi
2. Проверяем наличие устройства вообще:
DEV=$1
# check device exist
DOWN=`ifconfig -a | grep $DEV -c`
if [ $DOWN -eq 0 ]; then
if [ $SLNT -eq 0 ];then
echo "Device $DEV: NONE"
fi
exit 2
fi
3. Проверяем, работает оно или нет:
#check up/down status
UP=`ifconfig | grep $DEV -c`
if [ $UP -eq 0 ]; then #device down
if [ $SLNT -eq 0 ];then
echo "Device $DEV: DOWN"
fi
exit 1
else
if [ $SLNT -eq 0 ];then
echo "Device $DEV: UP"
fi
exit 0
fi
Я тут много писал о том, как запускать различные дистрибутивы по сети, однако, не написал, как, собственно, настроить PXE-сервер. Исправляю досадное упущение. Сервер поднимался на Slackware 14.2, на других линуксах должно быть примерно так же, за исключением того, что некоторый софт придется поставить. В Slackware все, кроме TFTP, было уже «из коробки», оставалось только настроить.
Структура каталогов
PXE-сервер занимает со всеми дистрибутивами довольно много места, у меня был довольно большой раздел /home, вот в нем я и создал подкаталог pxe, в котором создал два подкаталога scripts, для хранения скриптов, дополнительных утилит и бэкапов конфигов, и tftp — будущий корень TFTP-сервера, где завел отдельные подкаталоги для дистрибутивов (distrib) модулей сетевого загрузчика (modules) и загрузочного меню (pxelinux.cfg). В подкаталоге distrib для каждого дистрибутива по возможности создавался отдельный подкаталог. Пример дерева каталогов на PasteBin
TFTP
Ставим TFTP-сервер, я поставил такой же, как в статье, на которой основывался, настраивая сервер [1], atftp, а именно atftp-0.7.1. Поставил через sbopkg. На всякий случай готовый пакет
Поставили, теперь создадим файл /etc/tftpd.rules и запишем в него одну строку:
rg \\ /
Небольшое пояснение: Сетевой загрузчик, о котором будет сказано далее, обращается к TFTP-серверу на удаленной машине, чтобы подгрузить основные файлы — ядра Linux-дистрибутивов, собственные модули, файлы инициализационных RAM-дисков (initrd[.gz]), файлы образов ISO, дискет или жестких дисков. Файл /etc/tftpd.rules и правило rg \\ / нужно, чтобы TFTP-сервер распознал файлы, запрошенные Windows-загрузчиками (т.к. в Windows в качестве разделителя пути используется \, а в Linux /).
Без параметра -r blksize у меня TFTP глючил (о чем есть примечание в [1]), --blocksize 1456 несколько ускорил загрузку.
Параметр -s путь устанавливает корневой каталог TFTP-сервера (там будут лежать сетевой загрузчик, дополнительные модули и сами дистрибутивы, поэтому потребуется достаточно места). -v — заставляет сервер писать логи.
Остальные взял из [1]
Просмотр логов:
TFTP пишет логи в /var/log/messages и некоторые сообщения в /var/log/syslog.
Соответственно команды: grep tftp /var/log/messages
и grep tftp /var/log/syslog
Команды остановки сервера:
pkill in.tftpd
sleep 5
Samba
Сам сервер был доступен «из коробки»
Для виндовых дистрибутивов надо поднять Samba. Производим основные настройки в файле /etc/samba/smb.conf
[global]
workgroup = WORKGROUP
netbios name = PXE
server string = Local PXE
interfaces = 10.10.0.120
map to guest = bad user
security = USER
unix extensions = no
wide links = yes
follow symlinks = yes
log file = /var/log/samba/log.%m
max log size = 50
dns proxy = No
load printers = no
show add printer wizard = no
printcap name = /dev/null
disable spoolss = Yes
[printers]
comment = All Printers
path = /var/spool/samba
printable = Yes
browseable = No
workgroup — рабочая группа (поменяйте на свою) netbios name — имя компьютера server string — описание (видно в «Сетевом окружении» из Windows) interfaces — сетевой интерфейс, который будет прослушивать Samba-сервер. Можно выставить имена сетевых устройств (например, eth0) или задать IP
Делаем доступ к каталогам, открытым в Samba анонимным (без логина и пароля): map to guest = bad user
security = USER
Следующие 3 строки нужны, чтоб Samba стал поддерживать символические ссылки. У меня, например, дистрибутивы Windows 7 и 10 фактически лежат в каталоге FTP-сервера, а в каталоге дистрибутивов созданы символически ссылки, расшаренные в Samba: unix extensions = no
wide links = yes
follow symlinks = yes
log file — куда писать лог max log size — и его максимальный размер
По умолчанию отключаем DNS-proxy и доступ к принтерам: dns proxy = No
load printers = no
show add printer wizard = no
printcap name = /dev/null
disable spoolss = Yes
Секцию [printers] оставляем по умолчанию (все равно все настройки принтеров вырублены в [global], да и принтеров у меня на этом сервере не было).
Для запуска Samba в Slackware достаточно дать права на исполнение файлу /etc/rc.d/rc.samba и дать команду на запуск: chmod 744 /etc/rc.d/rc.samba
/etc/rc.d/rc.samba start
Остановка: /etc/rc.d/rc.samba stop Если не надо, чтоб сервер Samba стартовал при загрузке ОС, отбираем права на исполнение: chmod 644 /etc/rc.d/rc.samba
NFS нужен для запуска на удаленной машине некоторых дистрибутивов Linux. Смотрите подробности в соответствующих разделах, посвященных данным дистрибутивам.
В Slackware он так же шел «из коробки», а в конфиге нужно было прописать только конкретные каталоги, открытые для доступа по NFS.
Для запуска NFS нужно поставить права на исполнение следующим файлам:
Если не хотите, чтоб NFS автоматически поднимался при загрузке ОС, отберите права на исполнение: chmod 644 /etc/rc.d/rc.nfsd
chmod 644 /etc/rc.d/rc.rpc
Загрузка по сети устроена так, что BIOS (или EFI) целевой машины передает управление специальной микропрограмме-загрузчику, встроенному в микросхему сетевой карты. Тот пытается получить IP по DHCP, а потом подгрузить с машины, выдавшей IP, основной сетевой загрузчик. В некоторых случаях, если в сети уже есть другой DHCP это может вызвать глюки при загрузке (подробнее см. [1], там описаны конфигурации для сервера, если в сети, например, присутствует маршрутизатор CISCO, раздающий IP по DHCP).
Итак, DHCP надо настроить.
У меня с установкой соответствующего софта опять же, проблем не было, DHCP-сервер шел вместе с ОС, оставалось только настроить.
Копируем старый конфиг куда-нибудь, у меня DHCP до этого был не настроен, потому конфиг был пустой
Для корректной работы сервера, он должен быть сохранен под именем /etc/dhcpd.conf.
Если не нужно, чтобы DHCP-сервер стартовал постоянно, а, например, только на время работы PXE, то делаем так:
Старт DHCP-сервера:
echo "Copy DHCP daemon PXE config..."
#pxe config must be in current dir.
CURDIR=`pwd`
cp "$CURDIR/dhcpd.conf" /etc/dhcpd.conf
echo "Starting DHCP daemon..."
dhcpd
sleep 5
echo "Copy DHCP daemon PXE config..."
#pxe config must be in current dir.
CURDIR=`pwd`
cp "$CURDIR/dhcpd.conf" /etc/dhcpd.conf
echo "Starting DHCP daemon..."
dhcpd
sleep 5
На самом деле, загрузчик SYSLINUX — это целый комплекс загрузчиков, на все случаи жизни, здесь есть и сетевой — PXELINUX, и загрузчик для ISO-образов ISOLINUX и просто загрузчик ОС с жесткого диска. Пока нам потребуется только сетевой. SYSLINUX представляет собой операционную систему в миниатюре, загрузчик с помощью специальных команд, прописываемых в загрузочном меню, может выполнять специальные функции, сохраняемые в исполняемых файлах особого формата — модулях загрузчика. Обычно они имеют расширение *.c32, и плюс некоторые специальные файлы, например модуль memdisk, загружающий в память ISO-, Floppy- или HDD-образы.
Получение загрузчика: Проще всего его получить с официального сайта, скачав специальным скриптом. Скрипт разберет полученный архив на части, отдельно найдет в скачанном архиве модули *.32, memdisk и сетевой загрузчик pxelinux.0.
#!/bin/bash
SYSLINUXNAME="syslinux-4.02"
SYSLINUXADDR="https://www.kernel.org/pub/linux/utils/boot/syslinux/4.xx/$SYSLINUXNAME.tar.gz" #на Хабре использовали эту, пока оставим
WORKDIR="/tmp"
SERVERDIR="/home/pxe/tftp"
В оригинальной статье [1], была использована версия 4.02, если подумаете использовать какую-то другую, достаточно поменять данные в строке SYSLINUXNAME и/или SYSLINUXADDR
Далее перенесем все файлы *.c32 и memdisk в подкаталог modules (чтоб не мозолили глаза), а сетевой загрузчик pxelinux.0 оставим в корневом каталоге TFTP-сервера.
Тестовое меню
Теперь пишем минимальное тестовое меню, и проверяем запуск системы.
Добавим в меню загрузку с первого жесткого диска и перезагрузку машины:
Меню по умолчанию описывается в файле default, находящемся в подкаталоге pxelinux.cfg PXE-сервера, там же находятся и дополнительные меню, вызываемые из основного.
Сначала мы подгружаем специальный модуль пользовательского интерфейса modules/menu.c32, который отвечает за загрузку текстового интерфейса меню (подходит для любых компьютеров, даже самых слабых) ui modules/menu.c32
PROMPT 0 — отключение специального приглашения командной строки.
menu title ChaosServer PXE boot menu — заголовок меню.
Далее идут описания конкретных пунктов меню:
LABEL bootlocal
menu label Boot from first HDD
kernel modules/chain.c32
append hd0 0
timeout 11120
LABEL reboot
menu label Reboot
kernel modules/reboot.c32
параметр timeout включает отсчет времени до загрузки определенного пункта меню 1 единица после параметра timeout составляет 0.1 с
Описание некоторых модулей SYSLINUX
chain.c32 — переключает на следующий загрузчик (grldr, ntldr или просто на загрузчик, установленный на разделе HDD) reboot.c32 — перезагрузка компьютера menu.c32 — при использовании в меню, может загружать дополнительные меню (подменю), или производить переход назад/между меню. Пример использования:
Загрузка меню с утилитами Acronis:
LABEL acronis
menu label Acronis utilities
kernel modules/menu.c32
append pxelinux.cfg/acr
Возврат в основное меню:
LABEL back
menu label Back to main menu
kernel modules/menu.c32
append pxelinux.cfg/default
memdisk — специальный модуль, выполненный как псевоядро Линукс, может загружать образы ISO, HDD или дискет в оперативную память и передавать им дальнейшую загрузку. Пример использования:
LABEL acronis2011
menu label Acronis True Image 2011
kernel modules/memdisk
initrd distrib/acr/acronis2011/loader.iso
append iso raw
— createiso — скрипт для создания ISO-образов
— mknetboot.sh (скрипт для Puppy Slacko и подготовки к PXE-запуску этого дистрибутива)
— syslinux-install.bash — скрипт для скачивания SYSLINUX
1. Добавить текущий каталог в архив со всеми подкаталогами и файлами.
Т.е., если вы находитесь в каталоге /home/user/directory, то скрипт должен добавить в архив сам каталог, и все содержимое.
2. Добавить только содержимое (т.е. в архиве присутствует только содержимое каталога, но не сам каталог).
3. Вывод справки об использовании скрипта по ключу -h или --help
Ход мысли (описание алгоритма)
Чтобы заархивировать текущий каталог разными способами, надо добавить параметр. Пусть скрипт, запущенный без параметров, архивирует текущий каталог вместе с ним самим, а скрипт, запущенный с параметром -nc (no catalog), архивирует только содержимое. Еще надо вывести помощь, а если подсунули какой-то другой параметр, то отругаться и вывести помощь. Уточнение. Архив, из-за алгоритма работы архиватора, не сможет находиться в текущем каталоге, вне зависимости от того, с самим каталогом создается архив, или без. Архив надо создать в каталоге уровнем выше, а соответственно, предусмотреть ситуацию, когда пользователь вызывает скрипт из корневого каталога (выше него нет ничего). Уточнение #2. Поскольку, про имя архива ничего не сказано, имя архива будет текущий_каталог.tar.gz
Решение
1. Поскольку, помощь будет вызываться в двух случаях, напишем отдельную функцию, чтоб вызывать помощь, когда нужно:
print_help()
{
echo "Add current directory and subdirectories to tar.gz archive"
echo "Use "`basename $0`" [-nc]"
echo "[-nc] - add only content current directory (and subdirectories)."
echo
echo "Archive name == current directory name."
echo "Archive will be created to up-directory."
exit 1
}
2. Проверяем вызов помощи пользователем (в параметрах скрипта задано -h или --help):
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
print_help
fi
3. Проверяем, не запущен ли скрипт в корневом каталоге (/):
CURDIR=`pwd`
if [ "$CURDIR" == "/" ]; then
echo "Oh, no! It's root directory!"
exit 1
fi
Пояснение:`` обратные кавычки — те, которые, на клавише Ё, отправляют вывод работы команды в переменную. pwd выводит текущую директорию
4. Формируем имя архива и путь к нему и получаем имя текущего каталога
Пояснение: команда basename без дополнительных параметров, отрезает весь путь от имени файла, т.е. выводит на консоль только имя файла без относительного или абсолютного пути.
5. Если скрипту не заданы аргументы:
if [ $# -ne 1 ]; then
Пояснение: системная переменная $# хранит количество аргументов скрипта, заданных в командной строке.
запускаем архиватор, для создания архива вместе с текущим каталогом:
tar -czvf $ARHNAME "../"$DIRNAME
Пояснение:tar сам обрежет символы ../ и добавит, что надо.
6. Если параметр #1 скрипта присутствует, то проверяется, равен ли он -nc.
else
if [ "$1" == "-nc" ]; then
7. Если да, вызывается архиватор, архивирующий содержимое текущего каталога (без самого каталога):
tar -czvf $ARHNAME "."
8. Иначе, выводится сообщение о недопустимом значении параметра и помощь по использованию скрипта:
Это техническая страничка со списком дистрибутивов нашего PXE-сервера и ссылками на описание конкретных дистрибутивов. Страничка пополняется в зависимости от производственной необходимости, наличия оборудования, для которого понадобился тот или иной дистрибутив и времени.
Примечание: Альтернативный способ установки Windows 7/Vista/8/10.
Если не загрузилась Windows 7 PE или в ней что-то не работает.
1. Грузимся в какой-нибудь Linux, который видит сеть и умеет в Samba или FTP (FTP, естественно, надо поднять предварительно на сервере и скопировать в каталог, доступный через FTP, дистрибутив винды).
2. Делим диск и копируем винду на целевую машину, как это описано здесь (копия). Понятно, что вместо флешек с виндами используем FTP, Samba и возможности PXE-сервера.
3. Пользуемся Boot Windows from HDD или Boot Windows from HDD (DOS method) чтобы запустить установщик винды на целевой машине.
И ТЕЛЕМАРКЕТ!
Чтобы выйти из X (графического окружения) Puppy Slacko, и превратить его в полноценный консольный дистрибутив, например, если иксы глючат, достаточно нажать сочетание клавиш Ctrl+Alt+Backspace. Другой способ завершить иксы аварийно — переключиться в первую консоль (Ctrl+Alt+F1) и нажать Ctrl+C
Можно просто переключиться в консоль стандартным линуксовым способом, нажав Ctrl+Alt+F2 или Ctrl+Alt+F3 (это независимые консоли, кто не знает), тогда иксы останутся висеть в памяти, к ним можно вернуться, нажав Ctrl+Alt+F4.
Вводим логин root, пароль woofwoof и попадаем в голую консоль.
System Rescue CD — live CD, предназначенный для восстановления Linux-систем, основан на Gentoo, в комплекте довольно много полезностей. Можно использовать и как небольшой Live-дистрибутив Linux. Имеет графическую оболочку на Xfce (надо вызывать вручную командой startx, или через соответствующий параметр при загрузке). Решил добавить на наш PXE-сервер. Пока поставил не самую последнюю версию — 5.3.2, т.к. у этой версии есть возможность загружаться с 32 и 64-разрядным ядром (в более новых версиях поддержку x86 выпилили).
Подготовка дистрибутива и настройка NFS-сервера
1. Распаковываем ISO-образ
2. Создаем каталог на PXE-сервере, например /home/pxe/tftp/distrib/srcd/
3. Копируем в этот каталог файлы sysrcd.dat, sysrcd.md5 из корня, rescue32, rescue64 и initram.igz из каталога isolinux ISO-образа. Примечание:sysrcd.dat — сжатый Squash FS образ файловой системы ОС, при запуске скрипт в initrd проверяет его целостность по контрольной сумме, хранящейся в sysrcd.md5.
4. Открываем каталог для доступа по NFS, добавляем в /etc/exports строчку: /home/pxe/tftp/distrib/srcd/[пробел или табуляция]*(ro,no_subtree_check,all_squash,insecure)
5. Рестартируем NFS-сервер.
Настройка запуска
LABEL rescue32mem
menu label System Rescue CD x86 kernel (memory cache)
kernel distrib/srcd/rescue32
initrd distrib/srcd/initram.igz
append dodhcp nfsboot=10.10.0.120:/home/pxe/tftp/distrib/srcd/ nomodeset setkmap=us docache
dodhcp nfsboot=10.10.0.120:/home/pxe/tftp/distrib/srcd/ — указание получить IP от DHCP и NFS-каталог с соответствующего сервера. nomodeset — не использовать графические драйверы ядра для загрузки в консоль. Загрузится в нормальную консоль 80×25 setkmap=us — установить английскую раскладку клавиатуры (иначе будет спрашивать при загрузке) docache — подгрузить образ файловой системы (sysrcd.dat) в память. Требуется не менее 512 Мб оперативной памяти, но без этого параметра у меня System Rescue CD упорно не хотел грузиться (хотя, в итоговом меню оставил варианты и без docache с целью потом поэкспериментировать на других машинах).
Для запуска с 64-разрядным ядром меняем rescue32 на rescue64.
INX (расшифровывается как Is Not X), небольшой консольный, как ясно из названия, Live-дистрибутив Linux, основанный на Ubuntu. Обычно для разных целей я пользуюсь Puppy Slacko, но, как выяснилось, иметь live-дистрибутив без иксов, тоже полезно 🙂 В Слаке иксы на одной из машин безбожно заглючили. Всяческие DSL и тем более Linux For Scratch (читай самодельный дистрибутив) мне не подходили, потому что с ними может оказаться еще больше возни, или «из коробки» заглючит что-нибудь другое, или того хуже — сам чего-нибудь забудешь и недоложишь. А этот вроде выглядел вполне неплохо. В комплекте много всего, даже браузеры и консольные игры, есть mc, да и по заверениям разработчиков, требует он менее 100 Мб оперативной памяти, если загружен в обычном режиме. Поддерживается и режим to RAM, но тогда, как я понял, весь сжатый Squash FS образ системы грузится в память, и надо уже как минимум 200 Мб.
С интернетом, правда, небольшой баг. Надо вручную подправлять /etc/resolv.conf, иначе не будет DNS.
sudo mcedit /etc/resolv.conf
и меняем непонятный DNS, например на 8.8.8.8
Секунда ворчания
Вот уж некоторые, блин, линуксоиды профессиональные админы. Пишут инструкции, иногда упуская мелкие, но важные детали, которые, особенно если первый раз сталкиваешься, могут доставить неудобств. К вопросу, почему я стараюсь все подробно расписывать, во всяком случае, те грабли, на которые сам наступил.
Подготовка дистрибутива
1. Распаковываем или монтируем ISO-образ. (скачать с официального сайта)
2. Создаем каталог для дистрибутива там, где хранятся дистрибутивы PXE-сервера, в моем случае /home/pxe/tftp/distrib/linux/inx/
3. Копируем из подкаталога casper ISO-образа в созданный каталог файлы vmlinuzinitrd.gz
4. Создаем в /home/pxe/tftp/distrib/linux/inx/ подкаталог casper
5. Копируем в /home/pxe/tftp/distrib/linux/inx/casper из каталога casper ISO-образа файл filesystem.squashfs Этот файл обязательно должен лежать в подкаталоге casper каталога, который будет указан как nfsroot, иначе ядро его не найдет, и загрузка не получится.
Да, это была причина секунды ворчания. Целый час проковырялся. Об NFS ниже.
NFS-сервер
Для загрузки INX, кстати, как и других убунтовых дистрибутивов, по сети потребуется NFS-сервер. Тут я оставлю подробности, т.к. устанавливается он в разных Линуксах немного по-своему, а в Slackware, которая у меня, он шел «из коробки». Надо было только поставить права на исполнение двум скриптам /etc/rc.d/rc.nfsd и /etc/rc.d/rc.rpc.
После того, как сервер установлен, необходимо изменить файл /etc/exports чтобы открыть доступ к каталогу с дистрибутивом по NFS:
/home/pxe/tftp/distrib/linux/inx/[пробел или табуляция]*(ro,async,no_subtree_check,no_wdelay,insecure_locks,no_root_squash,insecure)
В качестве корневого каталога ОС (параметр root) указывается устройство /dev/nfs boot=casper — указание использовать Live-режим и искать основную ОС в файле сжатой файловой системы. netboot=nfs — указание произвести загрузку по сети, используя NFS nfsroot=10.10.0.120:/home/pxe/tftp/distrib/linux/inx/ — указание адреса (замените 10.10.0.120 на свой) и каталога на сервере (указывается с корня сервера). username, hostname и userfullname — соответственно, параметры для указания имени пользователя, имени компьютера и полного имени пользователя. Можно поставить свои, я оставил те, что были в конфиге isolinux из ISO-образа initrd=distrib/linux/inx/initrd.gz — указание, где искать инициализационный RAM-диск (задается относительно корня TFTP-сервера, т.к. initrd грузится по TFTP). vga=normal установка разрешения консоли (80×25 символов, ЕМНИС), или можно подсмотреть код оригинального в isolinux.cfg на диске, или, например, загрузившись с диска, почитать справку на этот счет. toram — загружать сжатый образ файловой системы (filesystem.squashfs) целиком в память. Без этого параметра — обращаться к нему по необходимости. Не знаю точно, работает ли параметр с загрузкой по сети, но вроде с ним загрузка проходит медленнее. Значит, похоже, если параметр toram не указан, то filesystem.squashfs по необходимости подчитывается из сети, и такой режим требует меньше памяти.
— Компьютер, с установленной Windows 7 🙂
— Достаточное место на HDD, со всеми потрохами этот процесс сожрал ~50Гб на диске.
— Образ Windows Automated Installation Kit (WAIK)
— WinBuilder — небольшая утилита, позволяющая автоматизировать процесс создания образа. О ней ниже.
— Чистый (!) образ установщика какой-нибудь одной версии Windows 7, сборки разной степени колхозности, а так же образы дисков все-в-одном (AIO) не подойдут. Скорее всего WinBuilder прекратит работу с какими-нибудь неудобоваримыми глюками. Поскольку я собрался делать образ x86 (32-разрядный), то и скачал Windows 7 Ultimate x86 с рутрекера.
— Универсальные наборы драйверов для сети, чипсетов и устройств хранения данных. О них ниже.
— Какая-нибудь виртуальная машина для тестирования полученного образа. У WinBuilder в комплекте есть QEMU, но желательно поставить VMWare, в нужный момент WinBuilder ее «подхватит», создаст свою виртуалку и запустит на ней образ
-cdrkit в Linux, для создания ISO-образа.
HBCD, как я уже говорил — «очень полезный горшочек», набор утилит для всяческого восстановления, форматирования, установки винды, и т.д.
Последняя версия, несмотря на то, что из нее убрали весь пиратский софт, стала только больше, и весит 700 Мб, хотя я помню версии по 250 Мб. Но можно распотрошить CD и грузить его по частям. Распакуем образ и приступим.
Это Linux-окружение для всяких работ с диском (делением на разделы, форматированием и т.д.). Но надо сказать, слегка капризное в отношении загрузки по сети.
Поскольку, программе мало ядра и initrd, лучше создать отдельный ISO-образ с ней. В каталог iso_root надо скопировать каталог pmagic из \Boot образа HBCD. Также нужно добавить загрузчик и составить соответствующие конфиги.
Вот переписанный с конфига HBCD конфиг для isolinux:
isolinux.cfgPasteBin (Mega.nz) — основное меню диска other.cfgPasteBin (Mega.nz) — дополнительные варианты загрузки, есть утилиты недоступные из основной конфигурации.
Главное, не забыть в каждую конфигурацию загрузки добавить опцию livemedia noeject, без нее не видит файлов из своей ФС.
1. Из \Boot HBCD копируются два файла SeagatDW и SeagatDW.gz в отдельный каталог.
2. Переименовываем строчными буквами (т.е. в sgdw и sgdw.gz)
3. Грузим, как обычный Linux-дистрибутив.
LABEL sd
menu label Seagate Disk Wizard
kernel distrib/hbcd/seagate/sgdw
initrd distrib/hbcd/seagate/sgdw.gz
append rw ramdisk_size=32768 acpi=off quiet noapic mbrcrcs on vga=788
Способ довольно странный, а само Linux-окружение для установки несколько кривовато, потому пишу больше чтоб тему закрыть и к установке XP более не возвращаться.
Принцип действия программы основан на возможности установки Windows XP из под DOS. Сначала по сети грузится специальный дистрибутив Linux (ядро и initrd), он настраивает сеть, подключает нужные сетевые шары, запускает предварительное конфигурирование, генерирует файл unattend.txt и разные послеустановочные скрипты, теоретически запускающие установку необходимых программ. На практике вся автоматизация работает криво (возможно, надо править скрипты и конфиги), но доступ к установщику винды, который думает, что запущен из-под DOS, мы в результате получаем.
Установка Linux-окружения
Вот где, кто и когда и откуда эту штуковину взял, я не ведаю. Поэтому вот вам архив прямо с сервера (естественно, без дистрибутива винды внутри).
Распаковываем содержимое каталога unatxp (внутри архива) куда-нибудь в отдельный подкаталог в каталоге с дистрибутивами на PXE-сервере.
Пусть будет для примера такой вот путь: /home/pxe/tftp/distrib/windows/unatwinxp
Настройка шары
Для работы установочному Linux-окружению необходимо расшарить каталог distrxp
Добавляем в smb.conf:
Дистрибутив XP надо скопировать с установочного диска или распаковать из ISO-образа и поместить в подкаталог distrxp/os/winxp, а также установить права на все файлы в подкаталогах в 755.
cd /home/pxe/tftp/distrib/windows/unatwinxp/distrxp/os/winxp
chmod -R 755 *
LABEL winxpunatted
menu label Windows XP Unattended install
kernel distrib/windows/unatwinxp/bzimage
initrd distrib/windows/unatwinxp/initrd.gz
append z_user=guest z_password=guest z_path=\\10.10.1.5\unatdistr
Как видно из кода выше, необходимо передать ядру Linux-окружения имя пользователя и пароль для доступа к шаре, а также ее адрес на сервере. Все данные передаются в соответствующих параметрах ядра.
Подготовка целевой машины
Теперь надо подготовить машину, на которую будем устанавливать XP. На самом деле, Linux-окружение само предложит переделить диск и сделать активный раздел при помощи своих инструментов, но я ему не особо доверяю, потому сделал это с помощью Acronis. Главное, чтоб перед установкой на машине уже был активный раздел, отформатированный в FAT32, иначе Linux-окружение перевет работу где-то на середине, и выбросит в линуксовую консоль, так и не запустив эмулятор DOS.
— Довольно кривое Linux-окружение
— Много мелких суетливых движений, как говорил классик. Необходимость отвечать на кучу вопросов.
— Требует раздел FAT32, потом придется переделывать командой convert.
+ Отсутствует возня с сетевыми драйверами и BINL
+ Идет даже на очень слабых машинах, тестировалось на PIII 700
Оказывается, на некоторых машинах такая конфигурация может неожиданно сглючить. Загрузчику 7 и 10 Windows почему-то периодически не нравится образ виртуального HDD с DOS. Переделал так, чтобы было без DOS-окружения совсем, а GRUB4DOS стартовал из загрузочного ISO-образа.
Загрузочное меню
Составляем загрузочное меню GRUB4DOS, в принципе, все делается по инструкции, нужен лишь редактор, поддерживающий переносы строк Windows/DOS (CR+LF). И стоит обратить внимание на то, что этот загрузчик GRUB4DOS чувствителен к регистру имен файлов, поэтому файл menu.lst необходимо назвать строчными буквами.
Загрузочный ISO я сделал в Linux, с помощью утилиты mkisofs.
1. Создаем где-нибудь в удобном месте каталог iso_root
2. Копируем в каталог файлы menu.lst, alt.lst и загрузчик GRUB4DOS grldr
3. В каталоге уровнем выше iso_root делаем скрипт для создания ISO-образа
Искал тут себе маленькие консольные (чтоб без иксов при старте) дистрибутивы Линукс. Перелопатил весь гугль. Вот меня пока два устроили, старейший, из мне известных System Rescue CD и INX, на основе Ubuntu, но без X-сервера. Он так и называется INX (Is Not X).
Mini Windows XP, «очень полезный горшочек», однако с запуском по сети возникают определенные сложности. Если просто загрузить образ Hiren’s Boot CD с помощью memdisk и запустить Mini Windows XP она свалится.
XP, что PE-версии, что инсталлятор, подружить с PXE проблематично. Мало того, что надо поднимать сервер BINL, который выдаст винде нужные драйвера для сетевых карт, так еще и задолбаешься настраивать загрузчик. Чего только не было — и штатный ntdetect.com не подходил, и патченные в упор не видели файлов ответа (winnt.sif), в общем геморроя было масса.
Но интересно, что Mini Windows XP вообще-то драйвера для сети при загрузке не нужны, все файлы на момент запуска уже переданы на целевую машину, и проблема в чем-то другом. Насколько я понял, в том, как memdisk маппит в память ISO-образ, а винда потом с этим делом конфликтует, скорее всего у нее не получается создать виртуальный диск в памяти. А если попробовать грузить не образ ISO, а образ HDD с виндой? Да! Таким макаром все вышло. Об этом и расскажу.
Необходимые инструменты
— Собственно, ISO-образ Hiren’s Boot CD 15.2
— Minimal DOS Image
— Какой-нибудь дистрибутив Linux, в который можно установить виртуальную машину QEMU. Мой пакет для Slackware здесь
— Утилита kpartx, из комплекта multipath-tools. Можно собрать/скачать самостоятельно. На всякий случай, пакет для Slackware
— Windows 7, если захочется провести более глубокую модификацию Mini Windows XP
— Текстовый редактор, поддерживающий переносы строк DOS/Windows (CR+LF), для редактирования конфигов и BAT-файлов DOS, Mini Windows XP и конфига загрузчика Grub4Dos (я делал это в винде).
Создание образа HDD с DOS
1. Складываем все инструменты в отдельный каталог в Linux, и создаем в нем «болванку», для образа HDD: dd if=/dev/zero of=winpe-test.img bs=90M count=1
Если создавать только минимально работающий Mini Windows XP, то хватит и 60 мегабайт (bs=60M), впрочем, можете попробовать поэкспериментировать и еще уменьшить его.
2. Грузимся в QEMU, указывая в качестве загрузочного устройства образ Hiren’s Boot CD, и приаттачиваем «болванку» образа HDD, как первый жесткий диск: qemu-system-i386 -cdrom hbcd.iso -hda winpe-test.img -boot d
3. Выбираем в меню загрузки Start Hiren’s Boot CD, потом File Managers и Volkov Commander
Загрузившись в VC вводим команду fdisk3. Эта команда запустит родной Fdisk от Microsoft’а.
У нас один жесткий диск, пока не форматированный и не размеченный, так что в появившемся меню нажимаем 1 и ENTER (Create DOS Partition or DOS logical drive), в следующем меню тоже выбираем 1 пункт (Create Primary DOS Partition), далее отвечаем Y (да). Если все сделано верно, Fdisk предложит перезагрузиться, дабы новый раздел стал доступен в DOS. Выходим из Fdisk и закрываем QEMU.
4. Грузимся в QEMU, но на этот раз указываем в качестве CD Minimal DOS Image:
qemu-system-i386 -cdrom dos.iso -hda winpe-test.img -boot d
Наш новый диск имеет букву D:, но недоступен, поскольку не отформатирован.
5. Форматируем его и делаем системным:
format D: /U /S
Подтверждаем операцию, по окончании вводим метку, например, WINPE.
6. Переходим на диск D (в меню Left—>Drive или Right—>Drive, QEMU перехватывает Alt+F1/Alt+F2), копируем с диска C: файлы autoexec.bat, config.sys, himem.sys и каталоги DOS и VC.
7. В оригинальном образе была опечатка в autoexec.bat, ее можно подправить, заменив строчку DOS;VC на C:\DOS;C:\VC
8. Можно проверить образ, загрузившись с него в том же QEMU: qemu-system-i386 -hda winpe-test.img -boot c
Должны появиться окошки Volkov Commander.
Монтирование (и размонтирование) образа диска
Для того, чтобы добавить на диск файлы WinPE, необходимо получить к нему доступ из Linux:
0. Создаем точку монтирования mkdir /mnt/dos
1. Вешаем образ на Loop-устройство: losetup /dev/loop0 winpe-test.img
Обычно устройство loop0 свободно, но можно посмотреть свободное командой losetup -f
2. Маппим разделы: kpartx -av /dev/loop0
Утилита выдаст сообщение, содержащее название обнаруженного раздела (выделено жирным): add map loop0p1 (251:6): 0 183393 linear /dev/loop0 63
3. Монтируем раздел: mount -t vfat /dev/mapper/loop0p1 /mnt/dos
После того, как нужные файлы скопированы, образ необходимо отключить.
1. Размонтируем раздел: umount /mnt/dos
2. Удаляем информацию о разделе: kpartx -dv /dev/loop0
Примечание: паузы нужны, иначе монтирование может случиться раньше, чем блочное устройство (раздел), появится в /dev/mapper и ничего не примонтируется.
Для создания минимально работающего Mini Windows XP, потребуется взять из образа Hiren’s Boot CD все файлы из \HBCD\XP, и положить их в каталог /HBCD/XP в образе жесткого диска.
Также необходимо настроить загрузчик Grub4Dos:
1. В образе Hiren’s Boot CD находим файл GRUB.EXE и копируем его в корень нашего диска.
2. Создаем конфиг MENU.LST также в корне диска. Я просто подправил оригинальный конфиг из Hiren’s Boot CD, удалив оттуда все лишнее. Содержимое конфига на PasteBin
Внимание! Править MENU.LST, AUTOEXEC.BAT, CONFIG.SYS надо редактором, который умеет в DOS/Windows переносы строк (например, Notepad++)
Проверяем.
1. Грузимся из полученного образа (здесь я делал это уже по сети, о настройке конфига для PXE будет ниже):
2. Запускаем GRUB.EXE:
3. Выбираем соответствующий пункт меню, ждем…
ФАНФАРЫ!
На самом деле, Mini Windows XP получился сильно урезанным, без программ из Hiren’s Boot CD, без толковой поддержки сети и прочих полезностей, что ж, будем улучшать
Добавляем важный софт.
Ну он не так, чтоб уж прямо критически важный, но Mini Windows XP подгружает некоторые программы, например, программу настройки сети, автомонтирования дисков, архиватор из \HBCD\Programs, \HBCD\Programs\Files\HBCD\Dos, я посмотрел в код файлов автозагрузки, и все самое важное выделил.
1. В /HBCD/Programs/Files нашего образа, добавим следующие файлы из \HBCD\Programs\Files ISO-образа: 7Zip.7z
AutoMountDrives.7z
DLL.7z
IrfanView.7z
Notepad.7z
TeraCopy.7z
XpFiles.7z
2. В /HBCD/Dos (из \HBCD\Dos): BiosBoot.7z
MBRUtil.7z
PCI32.7z
SavePart.7z
3. В /HBCD файл HBCDMenu.exe
4. В /HBCD/Programs пока можно скопировать все файлы, которые не *.cmd (из \HBCD\Programs ISO-образа), CMD-файлы, кроме одного (AutoMountDrives.cmd), придется подправлять, так что AutoMountDrives.cmd можно скопировать.
Лирическое отступление, или про то, как залезть во внутренности Mini Windows XP
Все потроха сего дистрибутива лежат в архиве формата WIM, в Windows 7 имеется стандартная утилита для работы с ним.
Копируем из образа HBCD файл XP.wim куда-нибудь в удобный каталог, и смотрим его содержимое (команды выполнять от администратора):
dism /Get-WimInfo /WimFile:XP.wim
Cистема DISM
Версия: 6.1.7600.16385
Сведения об образе : XP.wim
Индекс: 1
Имя : XP
Описание : <не определено>
Размер (байт): 113 236 979
Операция успешно завершена.
Образ можно подмонтировать в какой-нибудь каталог: mkdir %TMP%\wim
dism /Mount-Wim /WimFile:XP.wim /name:XP /MountDir:%TMP%\wim
Теперь в каталоге %TMP%\wim — содержимое образа, меня оттуда интересуют два файла: Startup.cmd, который Mini Windows XP запускает при старте, и prep, который в процессе загрузки переименовывается в Startup2.cmd и выполняется. Оттуда и из XpCustomize.cmd и были вытащены все нужные имена файлов.
Итак, что же все-таки делать с остальным софтом? Ну у нас же PXE, а значит есть сервер с Samba. В следующем выпуске я таки начну сначала, и расскажу, как настроить PXE на Linux-машине, и Samba в т.ч. Пока ограничусь секцией конфига smb.conf для этой конкретной шары:
В каталог /home/pxe/tftp/distrib/windows/winpe копируем каталог Files из ISO-образа HBCD, вместе со всем содержимым. Естественно, для шары вы можете указать любой удобный вам путь.
Подключение шары в Mini Windows XP
1. Правим файл /HBCD/XP/XpCustomize.cmd в нашем образе диска, меняем строку REM start PENetwork на start PENetwork
Эта команда запустит утилиту настройки сети (нужные драйвера уже есть в комплекте в архиве XpDrvLAN.7z и Mini Windows XP их подгружает, если вы не забыли положить в /HBCD/Programs файлы 7z.exe и 7z.dll)
2. Шара не поднимется, пока не будет настроена сеть, поэтому надо «притормозить» выполнение командного файла (обычно хватает полминуты). Для этого добавим в каталог /HBCD/XP утилиту sleep.exe (приложу ее в архиве ниже)
3. Пропишем следующие команды для паузы и поднятия шары. Шара будет подключена, как сетевой диск, например, с буквой W:
REM Add network share with programms
CD \HBCD\XP
sleep 30
Echo Add Files Share...
Если все сделано правильно, то после загрузки Mini Windows XP мы увидим сетевой диск в «Моем компьютере»:
А если зайдем внутрь, то файлы:
Исправляем CMD-файлы для запуска софта
1. Извлекаем из ISO-образа все CMD-файлы из \HBCD\Programs в отдельный каталог.
Во всех них, где есть (кроме файла AutoMountDrives.cmd) нужно заменить строчку Files\имя_файла на W:\Files\имя_файла (W: — сетевой диск, куда подключена шара)
2. Специально для этого дела я написал за 15 минут на коленке утилиту на C# — HBCDCmdFix
Пользоваться просто — выбираете каталог с *.cmd файлами и нажимаете Fix. Программа делает резервные копии в *.bak файлы перед изменением.
3. Кладем измененные файлы в /HBCD/Programs, отмонтируем образ нашего HDD, загружаемся с него и пробуем запустить какую-нибудь программу (из меню в системном трее). Если все сделано правильно, то программа запустится
Наводим красивости
Все готово, осталось только навести красоту в загрузочных меню.
Делаем в CONFIG.SYS загрузочное меню DOS (оставим возможность выйти в DOS или перезагрузить компьютер):
Измененный MENU.LST Grub4Dos (добавлена возможность перезагрузиться или выключить компьютер).
А симпатичную надпись в DOS’овом меню, я сделал, подправив в HEX-редакторе IO.SYS. Но как — догадайся мол сама 🙂
Готово!
Осталось только сжать готовые образы gzip‘ом и прописать в меню PXE-сервера:
gzip winpecut.img
gzip winpe.img
LABEL winxppe
menu label Windows XP PE
kernel modules/memdisk
initrd distrib/windows/winpe/winpe.img.gz
append harddisk
LABEL winxppecut
menu label Windows XP PE Very Small
kernel modules/memdisk
initrd distrib/windows/winpecut/winpecut.img.gz
append harddisk
Tinyproxy это такой маленький http/https прокси-сервер, на мой взгляд, очень простой в использовании и конфигурировании, вполне подходящий для несложных задач пропускания http(s) трафика. Например в офисе или дома. Лично я использую его, чтоб можно было посещать статистику и личный кабинет собственного провайдера в обход VPN.
Конфигурация network namespace.
Если у вас есть специальный network namespace для прокси, перед установкой сервера настраиваем его (добавляем нужные файлы hosts и resolv.conf, как это описано здесьКопия)
Рестартируем систему (или сетевой менеджер/демон, тут уж зависит от вашей ОС).
1. Создаем группу для proxy-сервера, например proxy:
groupadd proxy
2. Создаем отдельного пользователя для запуска прокси-сервера:
Можно сделать это с помощью скрипта-обертки adduser над программой useradd.
— На первый вопрос вводим имя пользователя, например, provproxy.
— Далее пропускаем (нажимаем enter)
— В ответ на initial group, вводим имя ранее созданной группы для прокси-сервера, в данном случае proxy (в вашем — ту группу, которую создали вы).
— Далее, на вопрос о дополнительных группах, нельзя устанавливать что-либо, нажимаем Enter
— Home directory нужна, там будет лежать PID-файл, логи (если нужно) и конфигурационный файл. По умолчанию директория совпадает с именем пользователя и располагается в подкаталоге /home.
— Shell должна быть установлена строго в /bin/false, поскольку это не интерактивный пользователь. Если скрипт ответил вам: - Warning: /bin/false is not in /etc/shells (potential problem using FTP)
Do you wish to change the shell ? (Y/n)
То отвечаем n, а потом в /etc/shells добавляем строчку /bin/false
— Expiry date пропускаем (Enter)
— Далее пропускаем всю User Information
— На вопрос о пароле придумываем что-нибудь чтоб прошло.
Далее правим /etc/shadow, находим строчку с именем пользователя и удаляем все, что между первым и вторым двоеточием. Было: provproxy:$5$S8/tp/ap2wF/K$qaYnfHuR8opsWO0WwTaXCjiHjmge7mWuH5WwEd5Kn70:17888:0:99 Стало: provproxy::17888:0:99 Права на каталог надо установить в 700 (полный доступ для пользователя provproxy): chmod 700 /home/provproxy
Можно не пользоваться интерактивным скриптом, а сделать все с помощью базовых команд:
1. Добавить пользователя useradd -g proxy -d /home/provproxy -s /bin/false provproxy
где: -g proxy группа пользователя (ранее созданная proxy) -d /home/provproxy домашний каталог пользователя -s /bin/false — оболочка для пользователя. Обычно здесь прописывается /bin/sh, /bin/bash для интерактивных пользователей, или /bin/false для неинтерактивных, что нам и надо в данном случае.
Строчка /bin/false должна быть в файле /etc/shells — если ее нет, дописать.
2. Создаем домашний каталог: mkdir /home/provproxy 3. Меняем владельца каталога на пользователя provproxy chown provproxy:proxy /home/provproxy 4. Меняем права доступа на каталог: chmod 700 /home/provproxy
Поскольку сам инициализационный скрипт описан довольно полно, то я остановлюсь лишь на двух важных моментах.
PID-файл: в скрипте необходимо правильно указать путь к PID-файлу, но об этом поговорим ниже. У меня PID-файл создается в домашнем каталоге пользователя provproxy. Местоположение PID-файла задается в этой строке скрипта. Если надо, не забудьте исправить на свое значение:
PIDFILE="/home/provproxy/tinyproxy.pid"
Команда запуска прокси-сервера:
По умолчанию там просто указан путь к исполняемому файлу tinyproxy:
TINYPROXYCMD="/usr/sbin/tinyproxy"
Но я хочу эту команду немного подправить.
Запуск сервера при старте системы.
При старте системы все обычно запускается от root‘а, а нам не надо совершенно, чтоб под root‘ом крутились всякие там сервера. Не зря же мы отдельного пользователя делали. Дополняем команду:
В таком виде, скрипт, запускаемый при старте из-под root‘а вызовет tinyproxy от имени нужного нам пользователя. Справедливости ради, надо заметить, что tinyproxy, как любой уважающий себя сервер, умеет сам себе понижать права до определенного пользователя, указанного в файле конфигурации. Но на этом остановимся ниже. На мой взгляд, одно другому не мешает, зато так виднее и жестко задано, от какого пользователя стартовать.
Альтернативный файл конфигурации.
По умолчанию tinyproxy ищет свой файл конфигурации в /etc/tinyproxy.conf, но можно задать альтернативный, в домашнем каталоге пользователя. Делается это путем добавления ключа -с и пути к файлу. Объединю этот вариант с предыдущим:
Альтернативный конфигурационный файл в домашнем каталоге.
Раз уж началось с альтернативного файла конфигурации, так давайте его сделаем (от root). Копируем файл /etc/tinyproxy.conf в /home/provproxy/tinyproxy.conf
Далее устанавливаем ему владельца (можно перейти в директорию /home/provproxy перед этим, я перешел — пути будут неполные):
chown provproxy:proxy tinyproxy.conf
И права — пользователю provproxy на tinyproxy.conf нужны права только на чтение, ничего он не пишет в конфигурационный файл, и тем более не пытается исполнить.
chmod 400 tinyproxy.conf
Конфигурирование.
Открываем файл от root‘а и настраиваем параметры прокси-сервера.
Это заметка от моего собственного склероза, потому что мелочи иногда забываю.
Для общей информации, что такое этот самый сетевой неймспейс. Это такая хитрая фиговина в ядре Linux, которая позволяет на одной машине с одной сетевой картой соединяться с сетью, будто у вас вагон и маленькая тележка этих сетевых карт (соответственно, куча локальных IP), можно, например, на одном неймспейсе поднять VPN до одного провайдера, на втором — до второго, на третьем — коннектиться к основному, и т.д.
Каждому из нэймспейсов можно подсунуть свою конфигурацию сети, свои конфигурационные файлы (resolv.conf, hosts)
Для этого достаточно положить соответствующие файлы в директорию /etc/netns/имя_namespace, например, для гипотетического namespace с именем riseupvpnns это будет каталог /etc/netns/riseupvpnns, туда можно положить, например, resolv.conf, прописать необходимые DNS, и эта конфигурация будет влиять только на данный namespace, в независимости, что там в основной системе прописано.
В первой части я показал, как просто обнаружить ошибки HTTP при работе с curl. Но на самом деле, подход, использованный в скрипте, немного неправильный:
Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода. В настоящее время выделено пять классов кодов состояния.
Т.е. объясняя по рабоче-крестьянски, не только код 200 может свидетельствовать об успешном завершении запроса, а другие коды, кроме явных клиентских или серверных ошибок, могут требовать от нас каких-либо действий.
Вообще, коды ответа HTTP разделены на 5 классов: 1xx — информационные 2xx — успешное завершение 3xx — требуется переопределение 4xx — ошибка, допущенная со стороны клиента 5xx — ошибка, допущенная со стороны сервера
Вот и модифицируем наш скрипт в соответствии со стандартом.
В общем, надо из кода ответа HTTP извлечь первую цифру, и, соответственно прореагировать. Привожу часть скрипта, ответственного за более подробную реакцию на код ответа HTTP:
Жирным шрифтом выделена строка, в которой мы получаем этот самый класс кода возврата.
Курсивом — строка, где мы получаем пояснения текстовые пояснения к коду ответа.
Используемая в процессе анализа утилита cut, в первом случае, позволяет нам вывести в переменную все символы после с третьего пробела.
Перед первым у нас версия протокола http, потом код ошибки, а потом пояснение, которое может содержать несколько пробелов, поэтому awk тут не подходит. cut так же может работать с текстовыми данными, в которых есть разделители, например пробелы, или же с отдельными символами, как в той строке кода, что выделена жирным — так мы можем извлечь первую цифру из кода ответа.
Дальнейший анализ осуществляется с помощью оператора case
Итак, возникла следующая задача — определить, когда curl получил вменяемые данные от http-сервера, а когда нет. В общем, и самом распространенном случае, задача сводится к тому, чтобы определить, отдал ли нам сервер запрашиваемый файл, или отобразил «страница не найдена».
Впрочем, это работает и для других возможных кодов ответа.
Ясно, что сервер, на наш запрос GET может ответить, как возвратив нам запрашиваемую страницу, так и отправив код, например, 404 (не найдено), и возвратив страницу-заглушку для этого случая. Так вот, на уровне скрипта bash или скрипта php необходимо проанализировать ответ сервера, чтобы не выдать пользователю вместо ожидаемых данных, всяческую лабуду. Далее я рассматриваю исключительно консольную Linux-утилиту curl. Для php, синтаксис, по-моему, отличается.
Есть страница, которую мы хотим получить: http://example.org/page.html, сохранить ее в файл page.html и есть curl, команда будет такая:
curl -o "page.html" http://example.org/page.html
Если страница на месте, то мы получим ее, и ничего анализировать не требуется.
Если же нет, то от большинства web-серверов мы получим страницу-заглушку, например такую, но никакой ошибки при этом.
Как же быть:
Проверяем код ошибки самого curl, если нет связи с сетью, URL неправильный, или задан неподдерживаемый curl протокол, если так, то мы получим соответствующий код возврата, наподобие:
curl: (1) Protocol htt not supported or disabled in libcurl
А вот если адрес правильный, и никакой ошибки в адресе или соединении нет, то код возврата не сработает, нам самим придется думать дальше.
Надо получить код ответа HTTP!
Сделать это можно, если получить отдельно заголовки ответа сервера, и после их проанализировать. Благо, для этого никакого страшного колдунства не требуется, достаточно указать утилите curl опцию -D (т.е. dump) и файл, куда выгружать заголовки.
Покажу это на примере конкретного скрипта:
#!/bin/bash
HEADERDUMP="/tmp/headerdump.txt"
SAVEFILE="/tmp/httpfile"
HTTPSTATUS=""
curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null
EXITCODE=$?
if [ $EXITCODE -ne 0 ]; then
echo "CURL error $EXITCODE"
else
HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`
if [ "$HTTPSTATUS" == "200" ];then
echo "OK"
else
echo "HTTP error $HTTPSTATUS"
fi
fi
заводим 3 переменные
HEADERDUMP="/tmp/headerdump.txt" — файл, в который будем получать заголовки SAVEFILE="/tmp/httpfile" — файл с сервера, который мы хотим получить HTTPSTATUS="" — переменная для статуса (состояния) HTTP
curl -o $SAVEFILE $1 -D $HEADERDUM
пытаемся скачать нужный файл (получить страницу): -o «имя_файла» — куда сохранять результат $1 — внутренняя переменная, первый параметр скрипта, при вызове его с командной строки. В своем скрипте надо заменить на свой случай.
можно добавить >/dev/null 2>/dev/null — для красоты, чтоб не вылезали сообщения о процессе и ошибках.
Еще со времен DOS можно было свистеть, гудеть и пикать встроенным динамиком компьютера, и даже симфонии играть. Сейчас это особо не нужно, ибо везде звуковые карты, динамики и прочая мультимедия. Но иногда PC-speaker нужная и полезная вещь, способная сигнализировать о чем либо, например, о разрыве соединения с Интернетом на домашнем сервере, к которому не подключен монитор, или о том, что торрент докачался. Да и вообще, способов, как можно применить спикер — множество. Даже симфонии можно играть.
Включение динамика
Зачастую, PC-speaker в линуксе отключен, точнее, не загружен модуль ядра, который им управляет. Обычно это модуль pcspkr, хотя, в некоторых источниках написано, что может быть и другой модуль snd-pcsp. У меня оказался первый.
Проверить, загружен ли соответствующий модуль ядра можно командами lsmod |grep pcspkr и lsmod |grep snd-pcsp соответственно.
Если команда ничего не выдала, то модуль не загружен.
Если выдала что-то похожее, значит, модуль загружен:
>lsmod |grep pcspkr
pcspkr 1448 0
Если модуль не загружен, нужно попробовать его загрузить:
modprobe pcspkr
или modprobe snd-pcsp
Если команда не выдала ошибки, модуль загружен. Можно проверить с помощью команды lsmod. Если случилась ошибка, то печально. Модуль, скорее всего, придется собирать. Ну, или не так печально, а даже наоборот — модуль встроен в ядро, и PC-speaker по умолчанию включен. Попробуйте простой beep.
Простой beep
Для простого beep достаточно отправить на консоль символ с кодом 007, ASCII-символ BEL
echo -ne '\007'
Способ может не сработать из SSH-терминала, либо из терминала X. Терминал SSH «булькнет» не на удаленном компьютере, а на локальном, а X-server может перенаправить beep на колонки, вместо PC-speaker’a
Утилита beep
Простые звуки и даже целые мелодии можно играть на спикере утилитой beep.
На рабочей машине она уже была в комплекте ОС, на Ubuntu ее можно установить командой apt-get install beep, а в Slackware она ставится через Sbopkg Проект имеется на Github, можно собрать и из исходников
Примеры вызова:
beep
Без параметров издаст стандартный beep
beep -f 500 -l 1000
Выдаст звук частотой 500 Гц, продолжительностью 1 секунду (1000 миллисекунд)
Примерскрипта, играющего тему Die Gedanken Sind Frei из ролика в начале заметки.