From 07db8ea4363bba0d00dde2d145d8e9ac3a1f188f Mon Sep 17 00:00:00 2001 From: erjemin Date: Mon, 22 Jun 2026 22:38:29 +0300 Subject: [PATCH] =?UTF-8?q?add:=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20b?= =?UTF-8?q?ash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 55 +++++++ bash/USAGE.md | 331 ++++++++++++++++++++++++++++++++++++++ bash/compare_modes.sh | 96 +++++++++++ bash/compare_servers.sh | 59 +++++++ bash/demo_gzip_problem.sh | 89 ++++++++++ bash/speed_test.sh | 280 ++++++++++++++++++++++++++++++++ 6 files changed, 910 insertions(+) create mode 100644 README.md create mode 100644 bash/USAGE.md create mode 100755 bash/compare_modes.sh create mode 100755 bash/compare_servers.sh create mode 100755 bash/demo_gzip_problem.sh create mode 100755 bash/speed_test.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..e94c9cb --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +![Static Badge](https://img.shields.io/badge/BASH-green) +![Static Badge](https://img.shields.io/badge/ТЕСТОВОЕ-ЗАДАНИЕ-grey) +![Version](https://img.shields.io/badge/version-0.1.0-blue) +![License](https://img.shields.io/badge/license-MIT-green) +[![Static Badge](https://img.shields.io/badge/ОРИГИНАЛ-git.cube2.ru-green)](https://git.cube2.ru/erjemin/2026-test-labor-02) + +# Тестовое задание от «Интерактивного агентства “Это Легко”» + +На соискание должности на вакансию [Python Developer](https://hh.ru/vacancy/134258608) + +## Задание + +> Написать скрипт-замерятель скорости интернета со своего компьютера. +> +> Он должен принимать адрес, куда стучаться (какая-нибудь тяжелая картинка), запускать последовательно 10 запросов к этому адресу, дожидаться ответа, вычислять среднее время запроса, объем скачанных данных и печатать в консоли скорость мб/с. +> +> Ответ залить на github и дать репозиторий с инструкциями. + +## Решение на Bash + +* Реализовано на чистом bash. Основной скрипт: **[speed_test.sh](bash/speed_test.sh)** +* Подробная документация: **[USAGE.md](bash/USAGE.md)** + +### Использование + +```bash +# Базовое использование +bash speed_test.sh -n 2 https://speedtest.selectel.ru/10MB + +# Тихий режим (только число) +bash speed_test.sh -q -n 3 https://speedtest.selectel.ru/10MB + +# Справка +bash speed_test.sh --help +``` + +### Основные возможности + +- Замер скорости через N последовательных запросов (`-n N`, по умолчанию 10) +- Два режима: реальная скорость канала (по умолчанию, с защитой от искажений из-за HTTP-сжатия) или эффективная скорость с gzip (`-g`) +- Тихий режим (`-q`) для использования в других скриптах +- **Цветной вывод** для лучшей читаемости (`--no-color` для отключения) +- Подробная статистика по каждому запросу + +### Требования + +- `bash` (3.0+) +- `curl` +- `bc` + +### Дополнительные скрипты + +- `bash/compare_servers.sh` — сравнение скорости разных серверов +- `bash/compare_modes.sh` — сравнение режимов (с/без gzip) +- `bash/demo_gzip_problem.sh` — демонстрация проблемы HTTP-сжатия diff --git a/bash/USAGE.md b/bash/USAGE.md new file mode 100644 index 0000000..de87ad5 --- /dev/null +++ b/bash/USAGE.md @@ -0,0 +1,331 @@ +# Инструкция по использованию скрипта замера скорости интернета + +## Описание + +`speed_test.sh` — это bash-скрипт для измерения скорости интернет-соединения путём последовательной загрузки файла с указанного URL. + +## Требования + +Скрипт использует стандартные утилиты, которые обычно предустановлены в большинстве Unix-подобных систем: +- `bash` — командная оболочка +- `curl` — утилита для загрузки данных по URL +- `bc` — калькулятор для вычислений с плавающей точкой +- `awk`, `seq` — стандартные утилиты + +### Установка зависимостей (если требуется) + +* **Ubuntu/Debian:** + ```bash + sudo apt-get install curl bc + ``` +* **macOS:** + ```bash + brew install curl bc + ``` +* **CentOS/RHEL:** + ```bash + sudo yum install curl bc + ``` +* **Fedora/RHEL:** + ```bash + sudo dnf install curl bc + ``` +* **Windows (через WSL):** + ```bash + sudo apt-get install curl bc + ``` + +## Использование + +### Базовое использование + +```bash +bash speed_test.sh [ОПЦИИ] +``` + +Где `` — адрес файла для загрузки (например, большая картинка или другой файл). + +### Опции + +- `-n, --count NUM` — Количество запросов для тестирования (по умолчанию: 10) +- `-q, --quiet` — Тихий режим: выводит только скорость в МБ/с (без единиц измерения, просто число) +- `-g, --gzip` — Разрешить HTTP-сжатие (gzip/deflate) для измерения эффективной скорости +- `-c, --no-color` — Отключить цветной вывод (по умолчанию цвета включены) +- `-h, --help` — Показать справку по использованию + +### Режимы измерения + +#### По умолчанию (без `-g`): Реальная скорость канала +Измеряет **реальную пропускную способность** интернет-канала: +- Отключает HTTP-сжатие (gzip/deflate) +- Показывает, сколько байт реально передаётся по сети +- **Используйте для:** тестирования скорости провайдера, VPN, выбора быстрого сервера + +#### С опцией `-g`: Эффективная скорость +Измеряет **эффективную скорость передачи данных**: +- Разрешает серверу использовать HTTP-сжатие +- Показывает, сколько полезных данных получено (после распаковки) +- Может быть в 2-10 раз выше для текстовых данных (HTML, JSON, CSS) +- **Используйте для:** оценки производительности веб-приложений, API + +**Тихий режим** особенно полезен для использования в других скриптах, где нужно получить только результат без дополнительного форматирования. + +### Примеры + +Тест с использованием готового тестового файла selectel.ru (Санкт-Петербург): +```bash +./speed_test.sh https://speedtest.selectel.ru/10MB +``` +Там же есть файлы других размеров, например: +- 100MB: `https://speedtest.selectel.ru/100MB` +- 1GB: `https://speedtest.selectel.ru/1GB` +- 10GB: `https://speedtest.selectel.ru/10GB` + +## Как работает скрипт + +1. **Проверка аргументов**: Скрипт проверяет, что передан URL для тестирования +2. **Серия запросов**: Выполняется 10 последовательных HTTP-запросов к указанному URL +3. **Замер параметров**: Для каждого запроса измеряется: + - Время выполнения (в секундах) + - Объём скачанных данных (в байтах) + - Скорость загрузки (в МБ/с) +4. **Вычисление средних значений**: После завершения всех запросов вычисляются: + - Среднее время запроса + - Общий и средний объём данных + - **Средняя скорость интернет-соединения в МБ/с** + +### Вывод скрипта + +#### Обычный режим + +Скрипт выводит: +- **Цветной заголовок** (можно отключить через `--no-color`) +- Информацию о каждом отдельном запросе с ✓ зелёной галочкой (время, объём, скорость) +- Итоговую статистику: + - Количество выполненных запросов + - Общее и среднее время + - Общий и средний объём данных + - **Среднюю скорость в МБ/с** + +#### Тихий режим (`-q` или `--quiet`) + +В тихом режиме скрипт выводит **только одно число** — среднюю скорость в МБ/с без единиц измерения. + +Это полезно для: +- Использования результата в других скриптах. +- Автоматизации тестирования. +- Сравнения разных серверов, CDN и VPN-подключений. +- Логирования результатов. + +Пример: +```bash +$ ./speed_test.sh -q -n 2 https://speedtest.selectel.ru/10MB +2.40 +``` + +### Пример вывода + +```text +============================================== +Замер скорости интернета +============================================== +URL: http://speedtest.ftp.otenet.gr/files/test10Mb.db +Количество запросов: 10 +============================================== + +Запрос 1/10... OK (11.039670s, 10.00 МБ, .90 МБ/с) +Запрос 2/10... OK (127.344702s, 10.00 МБ, .07 МБ/с) +... +Запрос 10/10... OK (3.832720s, 10.00 МБ, 2.60 МБ/с) + +============================================== +Результаты измерения +============================================== +Выполнено запросов: 10 +Общее время: 192.026102 сек +Среднее время запроса: 19.2026 сек +Общий объём данных: 100.00 МБ +Средний объём на запрос: 10.00 МБ + +============================================== +СРЕДНЯЯ СКОРОСТЬ: .52 МБ/с +============================================== +``` + +## Рекомендации по выбору URL для тестирования + +Для точного измерения скорости интернета рекомендуется: + +1. **Размер файла**: Используйте файлы размером от 5 МБ до 100 МБ + - Слишком маленькие файлы (< 1 МБ) дадут неточные результаты + - Слишком большие файлы (> 100 МБ) увеличат время тестирования + +2. **Стабильный сервер**: Выбирайте серверы с хорошей пропускной способностью + - Speedtest-серверы + - CDN-сервисы (Cloudflare, Akamai) + - Известные хостинги изображений + +3. **Географическая близость**: Для более точных результатов выбирайте серверы в вашем регионе + +### Рекомендуемые тестовые файлы + +**Selectel Speedtest (Россия):** +```bash +# 10 МБ файл (быстро, хорошо для частых тестов) +./speed_test.sh -n 5 https://speedtest.selectel.ru/10MB + +# 100 МБ файл (рекомендуется для точных измерений) +./speed_test.sh https://speedtest.selectel.ru/100MB + +# 1000 МБ (1 ГБ) файл (для очень стабильных каналов) +./speed_test.sh -n 3 https://speedtest.selectel.ru/1000MB +``` + +**Примечание:** Для больших файлов (100 МБ+) рекомендуется использовать меньшее количество запросов (2-5) для экономии времени и трафика. + +## Устранение неполадок + +### Ошибка: "curl: command not found" +**Решение**: Установите curl (см. раздел "Установка зависимостей") + +### Ошибка: "bc: command not found" +**Решение**: Установите bc (см. раздел "Установка зависимостей") + +### Ошибка: "Не удалось выполнить запрос" +**Возможные причины:** +- Неверный или недоступный URL +- Отсутствие интернет-соединения +- Сервер не отвечает или перегружен +- Файл был удалён + +**Решение**: Проверьте URL и подключение к интернету + +### Очень низкая скорость +**Возможные причины:** +- Медленный сервер источника +- Проблемы с вашим интернет-соединением +- Высокая загрузка сети + +**Решение**: Попробуйте другой URL или проверьте соединение + +## Технические детали + +### Единицы измерения + +- **МБ (мегабайт)** = 1 048 576 байт (1024 × 1024) +- Скрипт измеряет скорость в **МБ/с** (мегабайтах в секунду) +- Это отличается от **Мбит/с** (мегабит в секунду), которые часто используют провайдеры +- **Конверсия**: 1 МБ/с ≈ 8 Мбит/с + +### Метод расчёта + +Средняя скорость вычисляется как: +``` +Средняя скорость = (Общий объём данных в МБ) / (Общее время в секундах) +``` + +Этот метод даёт более точную картину реальной пропускной способности при последовательных запросах. + +### Защита от искажения результатов и режимы измерения + +**Проблема с HTTP-сжатием:** Многие веб-серверы используют gzip/deflate сжатие для экономии трафика. Это создаёт две разные метрики скорости: + +1. **Реальная скорость канала** — сколько байт фактически передаётся по сети +2. **Эффективная скорость** — сколько полезных данных получено после распаковки + +#### Режим по умолчанию: Реальная скорость канала + +Без опции `-g` скрипт измеряет **реальную пропускную способность** вашего интернет-канала: + +- **Что делает:** Добавляет HTTP-заголовок `Accept-Encoding: identity` +- **Эффект:** Запрещает серверу отправлять сжатые данные +- **Измеряет:** Реальный объём байт, переданных по сети +- **Используйте для:** + - Тестирования скорости интернет-провайдера + - Сравнения VPN-серверов + - Выбора быстрого CDN или зеркала + - Диагностики проблем с каналом + +**Пример:** +```bash +./speed_test.sh -n 5 https://speedtest.selectel.ru/10MB +# Результат: 2.5 МБ/с — реальная скорость вашего канала +``` + +#### Режим с опцией `-g`: Эффективная скорость + +С опцией `-g` скрипт измеряет **эффективную скорость** передачи данных: + +- **Что делает:** Разрешает серверу использовать gzip/deflate сжатие +- **Эффект:** Сервер сжимает данные перед отправкой, браузер распаковывает +- **Измеряет:** Объём полезных данных после распаковки +- **Может быть выше в 2-10 раз** для текстовых файлов (HTML, JSON, CSS, JS) +- **Используйте для:** + - Оценки производительности веб-приложений + - Тестирования API с JSON-ответами + - Понимания реальной скорости работы сайтов + +**Пример:** +```bash +./speed_test.sh -g -n 5 https://www.wikipedia.org/ +# Результат: 15.0 МБ/с — эффективная скорость с учётом сжатия +# (реальный канал 2.5 МБ/с, но благодаря gzip получили данных в 6 раз больше) +``` + +#### Сравнение режимов + +Файл `compare_modes.sh` демонстрирует разницу: +```bash +./compare_modes.sh https://example.com/ +``` + +**Типичные результаты:** +- **Бинарные файлы** (изображения, видео, архивы): разницы почти нет +- **Текстовые данные** (HTML, JSON, XML): эффективная скорость в 3-10 раз выше +- **Speedtest-файлы** (специально не сжимаются): режимы дают одинаковый результат + +**Вывод:** Используйте режим по умолчанию для честного замера скорости интернета. Используйте `-g` для оценки реальной производительности веб-приложений. + +## Модификация скрипта + +Вы можете легко изменить параметры в начале скрипта: + +```bash +# Изменить количество запросов (по умолчанию 10) +NUM_REQUESTS=20 + +# Добавить таймаут для curl (например, 30 секунд) +curl --max-time 30 -s -o /dev/null ... + +# Использовать другой метод HTTP (по умолчанию GET) +curl -X POST ... +``` + +## Использование в автоматизации + +### Пример: Поиск лучшего сервера + +В проекте включён пример скрипта `compare_servers.sh`, который показывает, как использовать тихий режим для сравнения скорости разных серверов: + +```bash +./compare_servers.sh +``` + +Этот скрипт: +1. Тестирует список серверов +2. Использует `speed_test.sh -q` для получения скорости каждого +3. Находит и выводит самый быстрый сервер + +Вы можете адаптировать этот пример для: +- Выбора лучшего VPN-сервера +- Тестирования разных CDN +- Мониторинга скорости интернета по расписанию +- Логирования производительности сети + +## Лицензия + +Скрипт предоставляется "как есть" для образовательных целей. + +## Автор: Sergei Erjemin (+Claude Sonnet 4.5 mini через CoPilot) + +Создано как решение тестового задания для вакансии "Python-разработчик" в "Интерактивное агентство 'Это Легко'". diff --git a/bash/compare_modes.sh b/bash/compare_modes.sh new file mode 100755 index 0000000..f28eb5f --- /dev/null +++ b/bash/compare_modes.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +# ============================================================================== +# Сравнение режимов замера скорости: без сжатия vs с gzip +# ============================================================================== +# Этот скрипт демонстрирует разницу между измерением реальной скорости канала +# и эффективной скорости с учётом HTTP-сжатия +# ============================================================================== + +echo "==============================================" +echo "Сравнение режимов замера скорости" +echo "==============================================" +echo "" + +# URL для тестирования - желательно файл, который хорошо сжимается +# Например, HTML, JSON, текст. Бинарные файлы (изображения, архивы) сжимаются плохо. +URL="${1:-https://www.wikipedia.org/}" + +echo "URL: $URL" +echo "" +echo "Выполняем 2 теста (по 2 запроса каждый)..." +echo "" + +# Тест 1: БЕЗ сжатия (реальная скорость интернет-канала) +echo "1️⃣ Режим: БЕЗ HTTP-сжатия (реальная скорость канала)" +echo " ./speed_test.sh -n 2 \"$URL\"" +echo "" + +speed_no_gzip=$(./speed_test.sh -q -n 2 "$URL" 2>/dev/null) +if [ $? -eq 0 ]; then + echo " ✅ Результат: ${speed_no_gzip} МБ/с" +else + echo " ❌ Ошибка измерения" + speed_no_gzip="0" +fi + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Тест 2: С сжатием (эффективная скорость передачи данных) +echo "2️⃣ Режим: С HTTP-сжатием (эффективная скорость)" +echo " ./speed_test.sh -g -n 2 \"$URL\"" +echo "" + +speed_with_gzip=$(./speed_test.sh -q -g -n 2 "$URL" 2>/dev/null) +if [ $? -eq 0 ]; then + echo " ✅ Результат: ${speed_with_gzip} МБ/с" +else + echo " ❌ Ошибка измерения" + speed_with_gzip="0" +fi + +echo "" +echo "==============================================" +echo "Итоги сравнения:" +echo "==============================================" +echo "" +echo "Без сжатия (реальный канал): ${speed_no_gzip} МБ/с" +echo "С сжатием (эффективная): ${speed_with_gzip} МБ/с" +echo "" + +# Вычисляем разницу если оба теста успешны +if (( $(echo "$speed_no_gzip > 0" | bc -l) )) && (( $(echo "$speed_with_gzip > 0" | bc -l) )); then + if (( $(echo "$speed_with_gzip > $speed_no_gzip" | bc -l) )); then + ratio=$(echo "scale=2; $speed_with_gzip / $speed_no_gzip" | bc) + improvement=$(echo "scale=1; ($speed_with_gzip - $speed_no_gzip) / $speed_no_gzip * 100" | bc) + + echo "📊 Выигрыш от сжатия: ${ratio}x (${improvement}% быстрее)" + echo "" + echo "💡 Интерпретация:" + echo " • Реальная пропускная способность канала: ${speed_no_gzip} МБ/с" + echo " • Благодаря HTTP-сжатию вы получаете данные эффективно," + echo " как если бы канал был быстрее в ${ratio}x раз!" + echo "" + echo " Это полезно для:" + echo " - Загрузки веб-страниц (HTML, CSS, JS)" + echo " - API с JSON-ответами" + echo " - Текстовых файлов" + elif (( $(echo "$speed_no_gzip > $speed_with_gzip" | bc -l) )); then + diff=$(echo "scale=2; $speed_no_gzip - $speed_with_gzip" | bc) + echo "⚠️ Скорость с сжатием немного ниже (разница: ${diff} МБ/с)" + echo "" + echo "💡 Возможные причины:" + echo " • Файл плохо сжимается (картинки, видео, архивы)" + echo " • Накладные расходы на сжатие/распаковку" + echo " • Вариация скорости сети между измерениями" + else + echo "Скорости примерно одинаковы - файл, вероятно, не сжимается" + fi +else + echo "⚠️ Не удалось выполнить сравнение" +fi + +echo "" +echo "==============================================" diff --git a/bash/compare_servers.sh b/bash/compare_servers.sh new file mode 100755 index 0000000..c9130f2 --- /dev/null +++ b/bash/compare_servers.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# ============================================================================== +# Пример использования speed_test.sh в тихом режиме +# Этот скрипт сравнивает скорость загрузки с разных серверов +# и находит самый быстрый +# ============================================================================== + +echo "Сравнение скорости загрузки с разных серверов..." +echo "" + +# Список серверов для тестирования +# Формат: "Название|URL" +servers=( + "Selectel 10MB|https://speedtest.selectel.ru/10MB" + "Selectel 100MB|https://speedtest.selectel.ru/100MB" +) + +# Переменные для отслеживания лучшего сервера +best_speed=0 +best_server="" + +# Тестируем каждый сервер +for server_info in "${servers[@]}"; do + # Разделяем название и URL + name=$(echo "$server_info" | cut -d'|' -f1) + url=$(echo "$server_info" | cut -d'|' -f2) + + echo -n "Тестирую $name... " + + # Запускаем тест в тихом режиме с 2 запросами для быстроты + speed=$(./speed_test.sh -q -n 2 "$url" 2>/dev/null) + + # Проверяем, успешно ли выполнен тест + if [ $? -eq 0 ] && [ -n "$speed" ]; then + echo "${speed} МБ/с" + + # Сравниваем со скоростью лучшего сервера + # bc возвращает 1 если первое число больше второго + is_better=$(echo "$speed > $best_speed" | bc -l) + if [ "$is_better" -eq 1 ]; then + best_speed=$speed + best_server=$name + fi + else + echo "ОШИБКА" + fi +done + +echo "" +echo "==============================================" +echo "Результат:" +if [ -n "$best_server" ]; then + echo "Самый быстрый сервер: $best_server" + echo "Скорость: ${best_speed} МБ/с" +else + echo "Не удалось найти работающий сервер" +fi +echo "==============================================" diff --git a/bash/demo_gzip_problem.sh b/bash/demo_gzip_problem.sh new file mode 100755 index 0000000..2c84387 --- /dev/null +++ b/bash/demo_gzip_problem.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# ============================================================================== +# Демонстрация проблемы с HTTP-сжатием при замере скорости +# ============================================================================== +# Этот скрипт показывает, как gzip-сжатие может исказить результаты измерения +# скорости интернет-соединения +# ============================================================================== + +echo "==============================================" +echo "Демонстрация проблемы с gzip-сжатием" +echo "==============================================" +echo "" + +# URL для тестирования (любой сервер, который поддерживает gzip) +# Обычно это текстовые файлы, HTML, JSON - они хорошо сжимаются +TEST_URL="https://www.wikipedia.org/" + +echo "Тестируем URL: $TEST_URL" +echo "" + +# Тест 1: БЕЗ отключения сжатия (по умолчанию curl запрашивает gzip) +echo "1. Запрос БЕЗ отключения gzip (curl по умолчанию):" +echo " curl -s -o /dev/null -w '...' $TEST_URL" +echo "" + +result_with_gzip=$(curl -s -o /dev/null -w "Время: %{time_total}s, Размер: %{size_download} байт" "$TEST_URL" 2>&1) +echo " Результат: $result_with_gzip" + +# Извлекаем размер +size_with_gzip=$(echo "$result_with_gzip" | grep -o 'Размер: [0-9]*' | awk '{print $2}') +echo "" + +# Тест 2: С отключением сжатия (как в нашем скрипте) +echo "2. Запрос С отключением gzip (Accept-Encoding: identity):" +echo " curl -H 'Accept-Encoding: identity' -s -o /dev/null -w '...' $TEST_URL" +echo "" + +result_without_gzip=$(curl -H "Accept-Encoding: identity" -s -o /dev/null -w "Время: %{time_total}s, Размер: %{size_download} байт" "$TEST_URL" 2>&1) +echo " Результат: $result_without_gzip" + +# Извлекаем размер +size_without_gzip=$(echo "$result_without_gzip" | grep -o 'Размер: [0-9]*' | awk '{print $2}') +echo "" + +echo "==============================================" +echo "Сравнение:" +echo "==============================================" + +if [ -n "$size_with_gzip" ] && [ -n "$size_without_gzip" ] && [ "$size_with_gzip" -gt 0 ]; then + # Вычисляем разницу + diff=$((size_without_gzip - size_with_gzip)) + + # Вычисляем коэффициент сжатия + if [ "$size_without_gzip" -gt 0 ]; then + ratio=$(echo "scale=2; $size_without_gzip / $size_with_gzip" | bc) + else + ratio="?" + fi + + echo "БЕЗ отключения gzip: $size_with_gzip байт" + echo "С отключением gzip: $size_without_gzip байт" + echo "Разница: $diff байт" + echo "Коэффициент сжатия: ${ratio}x" + echo "" + + if (( $(echo "$ratio > 1.5" | bc -l) )); then + echo "⚠️ ВНИМАНИЕ! Сжатие значительно уменьшило размер данных!" + echo " Если бы мы замеряли скорость без отключения gzip," + echo " результат был бы завышен примерно в ${ratio} раз!" + echo "" + echo " Пример: реальная скорость 10 МБ/с," + echo " но curl показал бы $(echo "scale=1; 10 * $ratio" | bc) МБ/с" + else + echo "ℹ️ Для этого URL сжатие минимально или отсутствует" + fi +else + echo "Не удалось получить корректные данные для сравнения" +fi + +echo "" +echo "==============================================" +echo "Вывод:" +echo "==============================================" +echo "Наш скрипт speed_test.sh использует" +echo " -H 'Accept-Encoding: identity'" +echo "чтобы гарантировать точные измерения" +echo "реальной скорости интернет-соединения!" +echo "==============================================" diff --git a/bash/speed_test.sh b/bash/speed_test.sh new file mode 100755 index 0000000..d127f2c --- /dev/null +++ b/bash/speed_test.sh @@ -0,0 +1,280 @@ +#!/bin/bash + +# ============================================================================== +# Скрипт для замера скорости интернета +# ============================================================================== +# Описание: +# Скрипт выполняет серию последовательных HTTP-запросов к указанному URL, +# замеряет время выполнения и объём скачанных данных, затем вычисляет +# среднюю скорость загрузки в МБ/с (мегабайтах в секунду) +# +# Использование: +# ./speed_test.sh +# +# Пример: +# ./speed_test.sh https://example.com/large_image.jpg +# ============================================================================== + +# Значения по умолчанию +NUM_REQUESTS=10 +URL="" +QUIET_MODE=false +ALLOW_COMPRESSION=false +USE_COLOR=true + +# ANSI цветовые коды +# Используем их только если цвета включены +COLOR_RESET='\033[0m' +COLOR_BOLD='\033[1m' +COLOR_RED='\033[0;31m' +COLOR_GREEN='\033[0;32m' +COLOR_YELLOW='\033[0;33m' +COLOR_BLUE='\033[0;34m' +COLOR_MAGENTA='\033[0;35m' +COLOR_CYAN='\033[0;36m' +COLOR_WHITE='\033[1;37m' + +# Функция для применения цвета (только если цвета включены) +colorize() { + local color="$1" + local text="$2" + if [ "$USE_COLOR" = true ]; then + echo -e "${color}${text}${COLOR_RESET}" + else + echo "$text" + fi +} + +# Функция для вывода без новой строки с цветом +colorize_n() { + local color="$1" + local text="$2" + if [ "$USE_COLOR" = true ]; then + echo -ne "${color}${text}${COLOR_RESET}" + else + echo -n "$text" + fi +} + +# Функция для вывода справки +show_help() { + echo "Использование: $0 [ОПЦИИ] " + echo "" + echo "Опции:" + echo " -n, --count NUM Количество запросов (по умолчанию: 10)" + echo " -q, --quiet Тихий режим: выводит только скорость в МБ/с" + echo " -g, --gzip Разрешить HTTP-сжатие (gzip/deflate)" + echo " -c, --no-color Отключить цветной вывод" + echo " -h, --help Показать эту справку" + echo "" + echo "Режимы измерения:" + echo " По умолчанию (без -g):" + echo " Измеряет РЕАЛЬНУЮ скорость интернет-канала" + echo " Отключает gzip-сжатие для точного замера трафика" + echo "" + echo " С опцией -g:" + echo " Измеряет ЭФФЕКТИВНУЮ скорость передачи данных" + echo " Разрешает серверу использовать сжатие" + echo " Полезно для оценки реальной производительности при работе" + echo "" + echo "Примеры:" + echo " $0 https://speedtest.selectel.ru/100MB" + echo " $0 --count 5 https://speedtest.selectel.ru/10MB" + echo " $0 -n 1 https://example.com/image.jpg" + echo " $0 -q -n 3 https://speedtest.selectel.ru/10MB" + echo " $0 --gzip -n 5 https://example.com/large.html" + echo "" + echo "Тихий режим полезен для использования в других скриптах:" + echo " speed=\$($0 -q -n 5 https://speedtest.selectel.ru/10MB)" + echo " echo \"Скорость: \${speed} МБ/с\"" + exit 0 +} + +# Парсинг аргументов командной строки +while [[ $# -gt 0 ]]; do + case $1 in + -n|--count) + # Проверяем, что следующий аргумент существует и является числом + if [ -z "$2" ] || ! [[ "$2" =~ ^[0-9]+$ ]]; then + echo "Ошибка: опция $1 требует числовое значение" + exit 1 + fi + NUM_REQUESTS="$2" + shift 2 + ;; + -q|--quiet) + QUIET_MODE=true + shift + ;; + -g|--gzip|--allow-compression) + ALLOW_COMPRESSION=true + shift + ;; + -c|--no-color) + USE_COLOR=false + shift + ;; + -h|--help) + show_help + ;; + -*) + echo "Ошибка: неизвестная опция $1" + echo "Используйте --help для справки" + exit 1 + ;; + *) + # Это должен быть URL + if [ -z "$URL" ]; then + URL="$1" + else + echo "Ошибка: указано более одного URL" + exit 1 + fi + shift + ;; + esac +done + +# Проверка наличия URL +if [ -z "$URL" ]; then + echo "Ошибка: не указан URL для тестирования" + echo "Использование: $0 [ОПЦИИ] " + echo "Используйте --help для подробной справки" + exit 1 +fi + +# Проверка, что количество запросов больше 0 +if [ "$NUM_REQUESTS" -le 0 ]; then + echo "Ошибка: количество запросов должно быть больше 0" + exit 1 +fi + +# Переменные для накопления результатов +total_time=0 # Общее время всех запросов (в секундах) +total_size=0 # Общий объём скачанных данных (в байтах) + +# Выводим заголовок только если не в тихом режиме +if [ "$QUIET_MODE" = false ]; then + colorize "$COLOR_CYAN" "==============================================" + colorize "$COLOR_BOLD$COLOR_WHITE" " Замер скорости интернета" + colorize "$COLOR_CYAN" "==============================================" + echo "URL: $URL" + echo "Количество запросов: $NUM_REQUESTS" + if [ "$ALLOW_COMPRESSION" = true ]; then + colorize "$COLOR_YELLOW" "Режим: с HTTP-сжатием (эффективная скорость)" + else + colorize "$COLOR_GREEN" "Режим: без сжатия (реальная скорость канала)" + fi + colorize "$COLOR_CYAN" "==============================================" + echo "" +fi + +# Выполняем серию последовательных запросов +for i in $(seq 1 $NUM_REQUESTS); do + # Выводим прогресс только если не в тихом режиме + if [ "$QUIET_MODE" = false ]; then + colorize_n "$COLOR_BLUE" "Запрос $i/$NUM_REQUESTS... " + fi + + # Используем curl для загрузки файла + # + # Режим сжатия определяется флагом ALLOW_COMPRESSION: + # + # БЕЗ сжатия (по умолчанию): + # -H "Accept-Encoding: identity" = отключаем gzip/deflate сжатие + # Важно! Без этого сервер может отправить сжатые данные, и мы будем + # измерять размер ПОСЛЕ распаковки, что исказит реальную скорость канала. + # Используйте этот режим для замера РЕАЛЬНОЙ скорости интернет-канала. + # + # С сжатием (опция --gzip): + # Без заголовка Accept-Encoding, curl автоматически запросит gzip + # Сервер может сжать данные, мы получим меньше байт по сети + # Но %{size_download} покажет распакованный размер + # Используйте этот режим для замера ЭФФЕКТИВНОЙ скорости передачи данных + # (полезно для веб-приложений, где сжатие обычно включено) + # + # -s = silent mode (без прогресс-бара) + # -o /dev/null = не сохраняем файл, отправляем в никуда + # -w = форматированный вывод статистики + # %{time_total} = общее время запроса в секундах + # %{size_download} = размер скачанных данных в байтах + + # Формируем команду curl в зависимости от режима + if [ "$ALLOW_COMPRESSION" = true ]; then + # Разрешаем сжатие (curl автоматически добавит Accept-Encoding: gzip, deflate) + output=$(curl -s -o /dev/null -w "%{time_total} %{size_download}" "$URL" 2>&1) + else + # Отключаем сжатие для точного замера сетевого трафика + output=$(curl -H "Accept-Encoding: identity" -s -o /dev/null -w "%{time_total} %{size_download}" "$URL" 2>&1) + fi + + # Проверяем код возврата curl + if [ $? -ne 0 ]; then + if [ "$QUIET_MODE" = false ]; then + colorize "$COLOR_RED" " ОШИБКА! Не удалось выполнить запрос" + echo "Возможные причины:" + echo " - Неверный URL" + echo " - Нет подключения к интернету" + echo " - Сервер недоступен" + fi + exit 1 + fi + + # Извлекаем время и размер из вывода curl + request_time=$(echo "$output" | awk '{print $1}') + request_size=$(echo "$output" | awk '{print $2}') + + # Проверяем, что получили корректные числа + if [ -z "$request_time" ] || [ -z "$request_size" ]; then + if [ "$QUIET_MODE" = false ]; then + colorize "$COLOR_RED" " ОШИБКА! Не удалось получить данные о запросе" + fi + exit 1 + fi + + # Накапливаем общее время и размер + total_time=$(echo "$total_time + $request_time" | bc) + total_size=$(echo "$total_size + $request_size" | bc) + + # Вычисляем скорость для текущего запроса в МБ/с (только если нужен вывод) + if [ "$QUIET_MODE" = false ]; then + # Размер в байтах / 1048576 = размер в мегабайтах (1 МБ = 1024*1024 байт) + # Скорость = размер_в_МБ / время_в_секундах + speed=$(echo "scale=2; ($request_size / 1048576) / $request_time" | bc) + size_mb=$(echo "scale=2; $request_size / 1048576" | bc) + colorize "$COLOR_GREEN" "✓ OK (${request_time}s, ${size_mb} МБ, ${speed} МБ/с)" + fi +done + +# Выводим итоговую статистику только если не в тихом режиме +if [ "$QUIET_MODE" = false ]; then + echo "" + colorize "$COLOR_CYAN" "==============================================" + colorize "$COLOR_BOLD$COLOR_WHITE" " Результаты измерения" + colorize "$COLOR_CYAN" "==============================================" +fi + +# Вычисляем средние значения +avg_time=$(echo "scale=4; $total_time / $NUM_REQUESTS" | bc) +total_size_mb=$(echo "scale=2; $total_size / 1048576" | bc) +avg_size_mb=$(echo "scale=2; $total_size_mb / $NUM_REQUESTS" | bc) + +# Вычисляем среднюю скорость +# Способ 1: общий объём / общее время (более точный для последовательных запросов) +avg_speed=$(echo "scale=2; $total_size_mb / $total_time" | bc) + +# В тихом режиме выводим только скорость +if [ "$QUIET_MODE" = true ]; then + echo "$avg_speed" +else + echo "Выполнено запросов: $NUM_REQUESTS" + echo "Общее время: ${total_time} сек" + echo "Среднее время запроса: ${avg_time} сек" + echo "Общий объём данных: ${total_size_mb} МБ" + echo "Средний объём на запрос: ${avg_size_mb} МБ" + echo "" + colorize "$COLOR_MAGENTA" "==============================================" + colorize "$COLOR_BOLD$COLOR_YELLOW" " СРЕДНЯЯ СКОРОСТЬ: ${avg_speed} МБ/с" + colorize "$COLOR_MAGENTA" "==============================================" + echo "" +fi