Внешний вид
Скрипты-оркестраторы: разбираем netlab-tmux.sh и пишем сами (Linux + Windows)
Что такое «скрипт-оркестратор»: не программа, а «пульт запуска» — проверяет окружение, поднимает зависимости, создаёт рабочее место (окна, вкладки, сессии) и подключает тебя туда. Наша цель: одна команда → готовое рабочее место, и запускать её можно хоть сто раз подряд.
Разберём ~/NetLab/netlab-tmux.sh досконально, потом выведем правила и перепишем идею под Windows.
1. Разбор netlab-tmux.sh построчно
bash
#!/bin/bashShebang — кто исполняет файл. Обязательна первая строка, иначе файл запустится «чем попало» при ./script.sh.
bash
set -eFail-fast: любая команда, вернувшая ошибку, немедленно роняет скрипт. Без этого скрипт пошёл бы дальше с полусломанным состоянием (например, создал бы сессию без окон). Компромисс: где ошибка допустима, пишем || true.
bash
cd "$(dirname "$0")"Переход в папку скрипта. $0 — путь, откуда запустили; dirname — его каталог. Зачем: скрипт ссылается на соседние файлы (./netlab-up.sh) и хочет работать вне зависимости от того, из какой папки его вызвали. Кавычки обязательны: пути с пробелами разорвут незакавыченный вариант.
bash
SESSION="NetLab"Константа вверху. Все настраиваемые значения — в начале файла, одним блоком. Правило: открыв скрипт, за 5 секунд понять, что он трогает.
bash
if ! ping -c1 -W2 192.168.122.10 >/dev/null 2>&1; then
./netlab-up.sh
sleep 40
fiGuard-проверка: «зависимость жива?» Вместо слепого «поднимем всё всегда» скрипт сначала спрашивает у реальности: CHR отвечает? Только если нет — тратит время на подъём. Это ключевой принцип — автодетект состояния вместо ритуалов (>/dev/null 2>&1 — прячем вывод: нам нужен только код возврата; ! — инверсия: «если НЕ пингуется»).
bash
if tmux has-session -t "$SESSION" 2>/dev/null; then
exec tmux attach -t "$SESSION"
fiИдемпотентность — главное качество оркестратора. Сессия уже существует? Не плодим вторую — просто подключаемся. 2>/dev/null глушит ошибку «нет такой сессии» (она ожидаема). exec — заменить процесс скрипта процессом tmux: скрипт завершится вместе с attach, лишний процесс не висит в памяти.
bash
tmux new-session -d -s "$SESSION" -n kimi -c "$HOME/NetLab" "kimi"
tmux new-window -t "$SESSION" -n chr -c "$HOME/NetLab" "ssh chr"
...Создание сущностей. -d — detached (не цепляемся сразу, собираем всё молча), -n — имя окна (видно в статусной строке), -c — стартовая папка окна, последний аргумент — команда, которая выполнится внутри. Имена kimi, chr, alpine1 — алиасы из ~/.ssh/config, так что никаких -i ключ в самом скрипте.
bash
tmux select-window -t "$SESSION:kimi"Финальный штрих: после сборки показать нужное окно, а не то, что создавалось последним.
bash
exec tmux attach -t "$SESSION"И только в конце — подключение. Структура скрипта: check → prepare → create → attach. Запомни эту схему — она универсальна.
2. Правила хорошего оркестратора (чек-лист)
- Одна команда — готовое место. Пользователь не должен помнить порядок действий.
- Идемпотентность. Запуск N раз = запуск 1 раза. Всегда проверяй «уже существует?».
- Автодетект, а не ритуал. Не «поднимай всё всегда», а «подними, только если мёртво» (ping/port-check/флаг-файл).
- Константы наверху, кавычки вокруг всех переменных,
set -e+ локальные|| trueгде фейл законен. - Именованные сущности (окна/сессии/контейнеры) — самодокументация.
- Человекочитаемый финал: вывести, что создано и как этим пользоваться.
- Не хранить секреты в скрипте — ссылки на алиасы SSH/переменные окружения.
3. Тот же пульт для Windows (PowerShell + Windows Terminal)
В Windows нет tmux, но есть его практический аналог — Windows Terminal (wt.exe): программируемые вкладки и панели из командной строки. А ssh.exe встроен в Windows 10/11. Тот же пульт, другой синтаксис — ~/NetLab/netlab.ps1:
powershell
#Requires -Version 5.1
# netlab.ps1 — рабочее место NetLab в Windows Terminal (аналог netlab-tmux.sh)
$ErrorActionPreference = 'Stop' # как "set -e": любая ошибка стоп
# --- 0. Guard: доступен ли CHR? (аналог ping-проверки) ---
$chrAlive = Test-Connection -TargetName 192.168.122.10 -Count 1 -Quiet -TimeoutSeconds 2
if (-not $chrAlive) {
Write-Host "CHR не отвечает. Лаба живёт на ноутбуке с Linux — подними её там (netlab-up.sh)." -ForegroundColor Yellow
# На Windows-машине можно лишь проверить сеть до неё; подъём VM здесь не делаем.
}
# --- 1. Открываем Windows Terminal с вкладками (wt — сам мультиплексирует) ---
# new-tab: каждая вкладка со своей командой; wsl ssh ... — если SSH-алиасы настроены в ~/.ssh/config WSL
wt --title "NetLab" new-tab --title "chr" ssh chr `; new-tab --title "alpine1" ssh alpine1 `; new-tab --title "alpine2" ssh alpine2Разбор PowerShell-конструкций (эквиваленты bash):
| Bash | PowerShell | Что делает |
|---|---|---|
set -e | $ErrorActionPreference = 'Stop' | падать при любой ошибке |
ping -c1 -W2 X | Test-Connection X -Count 1 -Quiet | проверка доступности (True/False) |
[[ -z "$x" ]] | [string]::IsNullOrEmpty($x) | проверка «пусто ли» |
if ! cmd; then | if (-not (Test-...)) | инверсия условия |
$1, $2 (аргументы) | $args[0] или param([string]$Name) | параметры |
echo "..." | Write-Host "..." | вывод |
exit 1 / $? | exit 1 / $LASTEXITCODE | коды возврата |
"$HOME/dir" | "$HOME\dir" / Join-Path $HOME 'dir' | пути (Join-Path — безопаснее) |
export VAR=x | $env:VAR = 'x' | переменные окружения |
И совсем короткий «голый» вариант без Windows Terminal — просто три окна PowerShell (если wt не установлен):
powershell
Start-Process powershell -ArgumentList '-NoExit','-Command','ssh chr'
Start-Process powershell -ArgumentList '-NoExit','-Command','ssh alpine1'
Start-Process powershell -ArgumentList '-NoExit','-Command','ssh alpine2'4. Порядок написания своего оркестратора
- Сначала вручную выполни сценарий один раз, записав каждую команду.
- Разложи команды по схеме check → prepare → create → attach.
- На каждом разрушающем/создающем шаге задай вопрос: «а если это уже есть?» — добавь guard.
- Все имена/пути/адреса — в константы наверху.
- Прогони три раза подряд: первый (создаёт), второй (подключается к существующему), третий после перезагрузки (восстанавливает) — все три должны заканчиваться одинаково: рабочим местом.
- В финале — инструкция пользователю (как переключаться, как выйти).
5. Проверь себя
- Зачем
execперед финальнымtmux attach, чем отличается от простоtmux attach? (Заменяет процесс скрипта: после выхода из tmux не остаётся висящего процесса-родителя.) - Что изменится, если убрать
set -eи первыйpingупадёт? (Скрипт полезет создавать сессию, даже если лаба не поднялась — получим окна с битым SSH.) - В PowerShell-версии мы НЕ стали поднимать лабу при мёртвом CHR. Почему это правильно для скрипта-оркестратора? (Оркестратор отвечает за то, что может контролировать; чужая инфраструктура → диагностика и подсказка человеку, а не слепые действия.)
См. также: Bash для сетевика (операторы, перенаправления, sed), Диагностика Windows-клиента (Win-экосистема: Test-NetConnection, netsh).