cl-remote: параллельное выполнение команд на рабочих станциях
Обновлено 9 ноября 2026
cl-remote — административная утилита: она параллельно по SSH выполняет команды и готовые служебные скрипты на множестве машин. Сначала утилита находит активные адреса в сети по открытому порту, затем подключается к каждой откликнувшейся машине и выводит результаты общей таблицей. Страница рассчитана на администраторов, которые обслуживают парк рабочих станций Calculate Linux.
Материал актуален для cl-remote 0.3.2.
Назначение
Потребность в ней возникает, когда одно действие нужно на десятках машин сразу: проверить версии сборок, найти, за какой станцией сидит сотрудник, разослать уведомления на рабочие столы, подготовить обновление из образа. По сравнению с ручным обходом ssh по одной машине cl-remote даёт:
- отсутствие агента на машинах: всё исполнение идёт по ssh штатными средствами целевой системы, а скрипты после работы на машине не остаются;
- быстрый отсев недоступных адресов: проверки порта идут параллельно и длятся не дольше таймаута SCAN_TIMEOUT на весь сегмент, поэтому выключенные машины не задерживают обход;
- параллельное выполнение с управляемой степенью параллелизма — параметром -j;
- отбор по вошедшим пользователям: выполнить действие там, где кто-то работает, или наоборот только там, где никого нет и перезагрузка безопасна;
- однократное описание сетей в конфигурационном файле — дальше они вызываются по имени, а не списком адресов;
- готовый набор скриптов для обслуживания парка: версии систем, пользователи, скорость интерфейсов, уведомления, обновление из образа, настройка точек доступа.
При этом утилита остаётся простым shell-инструментом: один вызов — одна таблица с результатом по каждой машине.
Установка
Утилита ставится из репозитория Calculate как пакет app-admin/cl-remote:
emerge -a cl-remote
Настройки читаются из файла /etc/calculate/remote.env — сразу после установки скопируйте в этот путь пример /etc/calculate/remote.env.example и раскомментируйте нужные строки. Без файла настроек утилита не работает.
cp /etc/calculate/remote.env.example /etc/calculate/remote.env
Подключение по SSH
cl-remote вызывает ssh без указания логина, поэтому учётную запись на целевой машине выбирает ssh-клиент. Саму утилиту на машине администратора может запустить любой пользователь — важно, чтобы системные действия на целевой машине выполнялись от root. Для этого запускайте cl-remote от root либо пропишите директиву User root в ~/.ssh/config клиента. В обоих случаях настройте безпарольный вход в root: сгенерируйте пару ключей (ssh-keygen -t ed25519), добавьте публичный ключ в корневую учётную запись машин (ssh-copy-id root@<адрес>) и укажите путь к закрытому ключу в переменной SSH_KEY.
Если вход по ключу не настроен, запускайте с параметром --ask-pass: утилита один раз запросит SSH-пароль и аутентифицирует им все подключения через sshpass. Без --ask-pass работает только вход по ключу: машина, не принявшая ключ, считается недоступной — дополнительных запросов утилита не делает.
Ключи серверов не проверяются
Подключение идёт без проверки открытого ключа целевой машины и без записи в known_hosts. Утилита рассчитывает на то, что адресам из ваших настроек доверяет администратор.
Настройка
cl-remote обнаруживает машины по порту: из всего списка адресов подключается к тем, у которых открыт порт-проба. По умолчанию это 22 — подходит, когда sshd работает на всех машинах парка. Чтобы отличить свои машины от прочего оборудования сети, выделите их дополнительным портом: настройте sshd принимать соединения и на нём, а номер укажите в NET_PORT. Обход сегмента из 254 адресов занимает меньше секунды, поэтому кэшировать результат обнаружения не нужно — каждый запуск находит машины заново.
Списки адресов и имена сетей хранятся в конфигурационном файле: NET_ADDR содержит пары «имя — диапазон адресов», NET_NAME — пары «имя — описание» (их показывает cl-remote -t list), а переменная NET задаёт сеть по умолчанию: без параметра -t работают именно с ней. NET_PORT задают в формате probe[:ssh]: первый порт — обнаружения, второй (при пропуске — общий SSH_PORT) — подключения.
Пример настроенного файла:
/etc/calculate/remote.env
# Сеть, используемая по умолчанию NET="labnet" # Имена сетей: пару имя — описание покажет cl-remote -t list NET_NAME=( labnet "Лабораторная сеть" officens "Офисная сеть" ) # Адресные диапазоны сетей: пару имя — список адресов NET_ADDR=( labnet "pc1 pc2 pc3" officens "192.168.1.{10..20}" ) # Порты сети в формате probe[:ssh] NET_PORT=( labnet "22" ) # Число одновременных подключений JOBS=10 # Закрытый ключ для passwordless-входа SSH_KEY="/root/.ssh/id_ed25519"
Зарегистрированные сети и сеть по умолчанию показывает запрос списка:
Сеть: [labnet] Лабораторная сеть [officens] Офисная сеть Сеть по умолчанию: labnet # Значение по умолчанию можно переопределить в 'remote.env'.
Мишени
Мишенью задают имя сети из настроек, IP-адрес, имя хоста или диапазон в фигурных скобках; параметр -t повторяется несколько раз. Команду можно послать и по всему сегменту — дойдёт только до откликнувшихся машин, а время обхода видно в последней строке таблицы:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ
--------------------------------------------------------------------------------
pc1 192.168.1.11 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
pc3 192.168.1.13 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
pc2 192.168.1.12 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
Всего: 3 Успешно: 3
Время выполнения: 0.1 сек.
В примерах — лабораторная подсеть администратора 192.168.1.0/24: машины pc1—pc3 отвечают на адресах 192.168.1.11—192.168.1.13; в своей сети подставьте рабочие адреса.
Лишние адреса снимаются из выборки параметром -x. Исключайте адрес в том же виде, в каком он попал в мишень: диапазоны — числами, сети — именами:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ
--------------------------------------------------------------------------------
pc1 192.168.1.11 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
pc3 192.168.1.13 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
Всего: 2 Успешно: 2
Время выполнения: 0.1 сек.
Если не указывать команду, утилита ограничится проверкой порта — так определяют, какие адреса в сегменте отвечают:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ -------------------------------------------------------------------------------- pc2 192.168.1.12 Порт 22 открыт. pc1 192.168.1.11 Порт 22 открыт. pc3 192.168.1.13 Порт 22 открыт. Всего: 3 Время выполнения: 0.0 сек.
Отбор машин по вошедшим пользователям
Параметр -u фильтрует машины по статусу входа ещё до выполнения команды: ON — только там, где кто-то работает; OFF — только там, где никого нет (безопасно для перезагрузок); логин — только там, где вошёл указанный пользователь; ALL (значение по умолчанию) — без фильтра. Так ищут, например, машины с незакрытой root-консолью:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ
--------------------------------------------------------------------------------
pc1 192.168.1.11 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
pc2 192.168.1.12 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
pc3 192.168.1.13 ivan pts/0 2026-11-09 09:17 (192.168.64.5)
petr pts/1 2026-11-09 09:47 (192.168.64.6)
root tty1 2026-11-09 08:47
Всего: 3 Успешно: 3
Время выполнения: 0.1 сек.
Машина, не прошедшая фильтр, в вывод не попадает: запуск с логином, под которым никто не входил, даёт пустую таблицу:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ -------------------------------------------------------------------------------- Время выполнения: 0.0 сек.
Готовые скрипты
Параметр -s выполняет скрипт из каталога /usr/libexec/cl-remote: скрипт целиком передаётся на машину, где запускается его функция run(); аргументы после имени скрипта становятся её параметрами. Аргумент list показывает сами скрипты, их описания и примеры вызова:
Системные скрипты:
[aproaming] Configuring OpenWrt access points with seamless Wi-Fi
roaming support (802.11r/k/v).
Example: cl-remote -t ap0812 -p 51022 -s aproaming
[rename-iface] Renaming the default network interface.
Udev in the initramfs assigns unique names to network
interfaces, which can be inconvenient to work with. This
script allows you to rename a network interface.
Warning: It's not recommended to use the name eth0 if
you have multiple network interfaces, as proper renaming
via systemd-udevd has been removed.
Example: 'cl-remote -s rename-iface lan0'
[users] Display system users
[version] Displaying the installed system version.
This script retrieves the installed version of
Calculate Linux. If an argument is provided, it compares
the version with the given value.
Example: 'cl-remote -s version 20250311'
[upgrade] Updating Calculate Linux from a system image without
modifying the existing installation
Example: 'cl-remote -j3 -s upgrade'
[notify] Sending Notifications to Users
Example: cl-remote -s notify "System Update" Reboot in
10 minutes!
[netspeed] Network Interface Speed
Displays the name and speed of the network interface.
If the speed does not match the maximum, an error is
displayed. Takes bridges into account.
Example: 'cl-remote -s netspeed'
Пользовательские скрипты:
[kernel] Отображение версии работающего ядра
Замеряется на целевой машине, вывод — строка uname -r
Пример: 'cl-remote -s kernel'
Проверка версии системы (version)
Скрипт читает номер сборки из /var/lib/calculate/calculate.env; если передать ему эталонный номер, отличившиеся машины будут помечены предупреждением:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ -------------------------------------------------------------------------------- pc3 192.168.1.13 20261030 pc2 192.168.1.12 20261030 pc1 192.168.1.11 20261030 Всего: 3 Предупреждения: 3 Время выполнения: 0.1 сек.
Машины ещё не обновились до свежего релиза 20261106: сборки отличаются от ожидаемой, и итог отнёс строки к предупреждениям.
Пользователи машины (users)
Скрипт показывает вошедших пользователей — полное имя из учётной записи и основную группу; вход root помечается предупреждением:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ
----------------------------------------------------------------------
Name Group
pc1 192.168.1.11 Ivan Petrov users
Petr Sidorov users
root root
Всего: 1 Предупреждения: 1
Время выполнения: 0.0 сек.
Уведомления на рабочие столы (notify)
Скрипт находит пользователей с открытым графическим сеансом и посылает каждому уведомление notify-send; заголовок — первый аргумент, остальное — текст уведомления. Время показа и значок задаются переменными NOTIFY_TIME и NOTIFY_ICON в /etc/calculate/remote-client.env.
Скорость сетевого интерфейса (netspeed)
Скрипт показывает интерфейс маршрута по умолчанию и его рабочую скорость; при наличии ethtool сравнивает её с максимально поддерживаемой и помечает предупреждением машины, работающие ниже своего лимита. Мосты учитываются: выводится физический интерфейс под мостом.
Обновление из образа (upgrade)
Скрипт запускает подготовку обновления из образа (cl-install -Uf) и перезагружает машину, только если на ней никто не работает. Операция тяжёлая, поэтому параллельные запуски ограничивают — как в примере из самого списка: cl-remote -j3 -s upgrade.
Унификация имён интерфейсов (rename-iface)
Udev в initramfs даёт интерфейсам имена по аппаратному расположению (enp19s0 и подобные), и на разных машинах они различаются. Смысл скрипта — привести имена локальных интерфейсов к общим для всего парка: интерфейс маршрута по умолчанию переименовывается в переданное имя (или в значение RENAME_IFACE), и на всех машинах он начинает называться одинаково — например, lan0. Кроме переименования скрипт правит /etc/conf.d/net и ссылки скриптов уровня запуска и записывает в /etc/udev/rules.d/70-persistent-net.rules правило, привязывающее имя к MAC-адресу, — имя сохраняется и после перезагрузки. На машинах с несколькими интерфейсами стандартным именем лучше не выбирать eth0.
Настройка точек доступа (aproaming)
Скрипт готовит точку доступа OpenWrt к бесшовному роумингу 802.11r/k/v. Имена сетей обоих диапазонов, Wi-Fi-пароль, регуляторный домен, ширину каналов, NTP и часовой пояс задают переменными с префиксом AP_ в /etc/calculate/remote-client.env; недостающий Wi-Fi-пароль утилита запрашивает при запуске.
Свои скрипты
Свой скрипт — обычный shell-файл. Основную часть кода выполняет функция run(), получающая аргументы, указанные после имени скрипта; необязательная функция prepare() запускается на машине администратора до рассылки и может, например, задать заголовок дополнительной колонки таблицы — для этого служит переменная CLIENT_TABLE_HEADER. Строки описания, начинающиеся с ##, попадают в список cl-remote -s list. Свои скрипты ищутся в первую очередь в пользовательском каталоге — по умолчанию это /var/calculate/remote-scripts, а путь к нему переопределяется переменной USER_SCRIPTS_DIR в /etc/calculate/remote.env; затем скрипт ищется среди системных в /usr/libexec/cl-remote. Готовые скрипты из этого каталога можно брать за основу при написании своих. Значения из /etc/calculate/remote-client.env и то, что собрала prepare(), передаются на целевую машину вместе со скриптом; на самой машине от скрипта ничего не остаётся.
Пример скрипта, показывающего версию ядра:
/var/calculate/remote-scripts/kernel
## Отображение версии работающего ядра ## Замеряется на целевой машине, вывод — строка uname -r ## Пример: 'cl-remote -s kernel' run() { uname -r }
Запуск своего скрипта на машине:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ -------------------------------------------------------------------------------- pc1 192.168.1.11 6.18.57-calculate Всего: 1 Успешно: 1 Время выполнения: 0.0 сек.
Вывод результатов
Каждая обработанная машина — строка таблицы из колонок ИМЯ ХОСТА, IP и РЕЗУЛЬТАТ; многострочный вывод команды выравнивается по третьей колонке. Строки окрашиваются по исходу: зелёным — успех, жёлтым — предупреждение, красным — ошибка; готовый скрипт помечает результат предупреждением кодом выхода 73. Порядок строк — по мере готовности, не по алфавиту. В конце — счётчики итогов и время выполнения.
Фильтр по уровню -r оставляет в выводе строки только нужного класса:
ИМЯ ХОСТА IP РЕЗУЛЬТАТ -------------------------------------------------------------------------------- Время выполнения: 0.0 сек.
Параметр --nocolor отключает цвета (при перенаправлении в файл утилита делает это сама).
Параметры
| Параметр | Значение | Действие |
|---|---|---|
--ask-pass |
— | Спросить SSH-пароль и аутентифицироваться через sshpass |
-x, --exclude |
сеть / адрес / имя | Исключить из выборки; повторяется |
-h, --help |
— | Показать справку |
-j, --jobs |
число (10) | Количество одновременных подключений |
--nocolor |
— | Отключить цветной вывод |
-p, --probe-port |
порт (22) | Порт для проверки доступности машины |
-P, --ssh-port |
порт (22) | Порт подключения по SSH |
-r, --report |
all / success / warning / error | Оставлять в выводе строки только этого уровня |
-s, --script |
имя или list | Выполнить готовый скрипт; list — показать список |
-t, --target |
сеть / адрес / имя | Задать мишень; повторяется |
-u, --using |
ALL / ON / OFF / логин | Выполнять с учётом вошедших пользователей |
Полный список с примерами — справка cl-remote --help.
Переменные настройки
Значения задаются в /etc/calculate/remote.env (кроме переменных для готовых скриптов — они живут в /etc/calculate/remote-client.env).
| Переменная | По умолчанию | Назначение |
|---|---|---|
EXEC_TIMEOUT |
1200 | Ограничение времени выполнения команды на машине, секунды |
JOBS |
10 | Количество одновременных подключений |
NET |
— | Сеть по умолчанию для запуска без -t |
NET_ADDR |
— | Пары «имя сети — список адресов» |
NET_NAME |
— | Пары «имя сети — описание» для -t list |
NET_PORT |
— | Пары «имя сети — probe[:ssh]» |
PROBE_PORT |
22 | Порт проверки доступности машины |
SCAN_TIMEOUT |
1.5 | Таймаут проверки порта, секунды |
SSH_KEY |
— | Путь к закрытому SSH-ключу |
SSH_PORT |
22 | Порт подключения по SSH |
USING |
ALL | Фильтр по вошедшим пользователям по умолчанию |
USER_SCRIPTS_DIR |
/var/calculate/remote-scripts | Каталог своих скриптов |
Исходный репозиторий и дополнительные примеры: git.calculate-linux.org/calculate/cl-remote
Другие руководства по администрированию — на странице Работа с Calculate.