Проверка скорости интернета через консоль

Продолжаю мучить bash. Задача — измерять скорость интернета через консоль. Когда-то была нормальная утилита speedtest, которая делала это через одноимённый сервис, быстро и наглядно. Но кому-то в Минцифры не понравилось, что под трафик этого сервиса маскируются vpn-ы и его заблочили.

Появился новый сервис, Яндекс Интернетометр. Выглядит так:

Яндекс Интернетометр.

В принципе, для измерения через браузер, ок, но что если мы хотим всё же через консоль?

Я сделал несколько попыток исследовать сервис, но не нашёл ни официальных, ни хакерских способов это сделать. Написал письмо в техподдержку, мне ответили, что направят вопрос разработчикам.

А пока я, вместе со своим электронным хоуми, написал вот такую обёртку для проверки скорости через cloudflare.com

#!/opt/homebrew/bin/bash

# =============================================================================
# 🚀 Speedi - Тестер скорости интернет-соединения
# =============================================================================
#
# Этот скрипт измеряет скорость интернет-соединения, включая:
# - Скорость загрузки (download)
# - Скорость отправки (upload)
#
# Использует сервис speed.cloudflare.com для проведения тестов.
# Результаты выводятся в мегабитах в секунду (Mbit/s).
#
# Автор: Владимир Бычко, Chat GPT, SourseCraft Code Assistant
# Дата: 2025
# =============================================================================

# Включаем режим строгой обработки ошибок
# Скрипт завершится при любой ошибке
set -e

# =============================================================================
# 🔧 Глобальные переменные и константы
# =============================================================================

# URL для тестирования скорости загрузки (10 МБ файл)
readonly DOWNLOAD_URL="https://speed.cloudflare.com/__down?bytes=10000000"

# URL для тестирования скорости отправки
readonly UPLOAD_URL="https://speed.cloudflare.com/__up"

# Размер данных для теста отправки (в мегабайтах)
readonly UPLOAD_SIZE_MB=10

# =============================================================================
# 📦 Функции проверки зависимостей
# =============================================================================

# Проверяет наличие необходимых утилит в системе
check_dependencies() {
    local missing_tools=()

    # Проверяем curl
    if ! command -v curl &>/dev/null; then
        missing_tools+=("curl")
    fi

    # Проверяем bc
    if ! command -v bc &>/dev/null; then
        missing_tools+=("bc")
    fi

    # Если есть отсутствующие инструменты, выводим ошибку и завершаем работу
    if [ ${#missing_tools[@]} -ne 0 ]; then
        echo "❌ Ошибка: Отсутствуют необходимые инструменты: ${missing_tools[*]}"
        echo "Пожалуйста, установите их и повторите попытку."
        exit 1
    fi
}


# =============================================================================
# 🌐 Функция проверки подключения к интернету
# =============================================================================

# Проверяет, доступен ли сервис speed.cloudflare.com
check_internet_connection() {
    echo "🌐 Проверяем подключение к интернету..."

    # Пытаемся получить заголовки от speed.cloudflare.com
    # Используем таймаут 10 секунд для предотвращения зависания
    if ! curl --silent --fail --max-time 10 --head "https://speed.cloudflare.com" &>/dev/null; then
        echo "❌ Сервис проверки скорости недоступен, вероятно, на комьютере не работает интернет"
        exit 1
    fi

    echo "✅ Подключение к интернету установлено"
}

# =============================================================================
# 📊 Функции преобразования и форматирования данных
# =============================================================================

# Преобразует скорость из байтов/сек в мегабиты/сек
# Аргументы:
#   $1 - скорость в байтах/сек
# Возвращает:
#   скорость в мегабитах/сек
convert_to_mbps() {
    local bytes_per_sec=$1

    # Проверяем, что передано корректное значение
    if [[ -z "$bytes_per_sec" || "$bytes_per_sec" == "0" ]]; then
        echo "0"
        return
    fi

    # Преобразуем байты в секунду в мегабиты в секунду
    # 1 байт = 8 бит, 1 Мбит = 1000000 бит
    echo "$bytes_per_sec*8/1000000" | bc -l
}

# Форматирует и выводит результат скорости
# Аргументы:
#   $1 - тип теста (загрузка/отправка)
#   $2 - скорость в мегабитах/сек
print_speed_result() {
    local test_type=$1
    local mbps=$2

    # Выводим результат с двумя знаками после запятой
    awk -v test_type="$test_type" -v mbps="$mbps" 'BEGIN {
        printf "⚙️  %-15s: %8.2f Mbit/s\n", test_type, mbps
    }'
}

# =============================================================================
# 📈 Функции тестирования скорости
# =============================================================================

# Тестирует скорость загрузки данных
test_download_speed() {
    echo "⬇️  Тестируем скорость загрузки..."

    # Измеряем скорость загрузки в байтах в секунду
    local bytes_per_sec
    bytes_per_sec=$(curl -L --silent --output /dev/null --write-out "%{speed_download}\n" "$DOWNLOAD_URL")

    # Проверяем, что получили корректное значение
    if [[ -z "$bytes_per_sec" || "$bytes_per_sec" == "0" ]]; then
        echo "❌ Ошибка: Не удалось получить скорость загрузки"
        return 1
    fi

    # Преобразуем и выводим результат
    local mbps
    mbps=$(convert_to_mbps "$bytes_per_sec")
    print_speed_result "Скорость загрузки" "$mbps"
}

# Тестирует скорость отправки данных
test_upload_speed() {
    echo "⬆️  Тестируем скорость отправки..."

    # Генерируем случайные данные и отправляем их на сервер
    # Используем /dev/zero для генерации данных без записи на диск
    local bytes_per_sec
    bytes_per_sec=$(dd if=/dev/zero bs=1M count=$UPLOAD_SIZE_MB 2>/dev/null | \
        curl -X POST --silent --output /dev/null --write-out "%{speed_upload}\n" \
        -H "Content-Type: application/octet-stream" \
        --data-binary @- "$UPLOAD_URL")

    # Проверяем, что получили корректное значение
    if [[ -z "$bytes_per_sec" || "$bytes_per_sec" == "0" ]]; then
        echo "❌ Ошибка: Не удалось получить скорость отправки"
        return 1
    fi

    # Преобразуем и выводим результат
    local mbps
    mbps=$(convert_to_mbps "$bytes_per_sec")
    print_speed_result "Скорость отправки" "$mbps"
}

# =============================================================================
# 🎛️ Основная функция и точка входа в программу
# =============================================================================

# Отображает справку по использованию скрипта
show_help() {
    echo "🚀 Speedi - Тестер скорости интернет-соединения"
    echo ""
    echo "Использование:"
    echo "  speedi          # Запустить тест скорости"
    echo "  speedi --help   # Показать эту справку"
    echo ""
    echo "Описание:"
    echo "  Скрипт измеряет скорость интернет-соединения, используя сервис"
    echo "  speed.cloudflare.com. Тест включает в себя измерение скорости"
    echo "  загрузки и отправки данных."
    echo ""
    echo "Результаты:"
    echo "  Скорость отображается в мегабитах в секунду (Mbit/s)."
}

# Основная функция скрипта
main() {
    # Проверяем аргументы командной строки
    case "${1:-}" in
        --help|-h|help)
            show_help
            exit 0
            ;;
        "")
            # Нет аргументов - запускаем тест
            ;;
        *)
            echo "Неизвестный аргумент: $1"
            echo "Используйте --help для получения справки."
            exit 1
            ;;
    esac

    # Выводим приветствие
    echo "🚀 Speedi - Тестер скорости интернет-соединения"
    echo "================================================"
    echo ""

    # Проверяем подключение к интернету
    check_internet_connection

    # Проверяем зависимости
    check_dependencies

    # Запускаем тесты
    test_download_speed
    echo ""
    test_upload_speed

    # Завершаем работу
    echo ""
    echo "✅ Тестирование завершено!"
}

# Точка входа в скрипт
main "$@"

Я не стал заморачиваться со скачиванием curl и bc, в случае отсутствия, хз какие никсы стоят у вас, если вы хотите измерять скорость интернета через консоль, с установкой утилит справитесь.

Выглядит использование так:

В общем, наслаждайтесь.

UPD: На самом деле, вы можете измерить скорость вот такой командой:

npx speed-cloudflare-cli

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


Опубликовано

в

,

от

Метки:

Подпишитесь на новые посты, чтобы не пропускать их (РКН о сборе имейлов уведомлён должным образом):

Предыдущий пост
Способ немного заморочиться и организовать перезагрузку роутера Keneetic одной командой…