Zwei Maengel aus dem Rundgang vom 22.8. behoben. 1. STOPP-KNOPF. Die Konsole nannte "⏹ Aufzeichnung stoppen", es gab ihn nicht. Christoph drueckte "Call beendet" und den Not-Aus -- beide schreiben nur Marken -- und die Messung lief weiter, waehrend der Core sein Telefon mit 5 Pings/s bearbeitete. Jetzt legt der Knopf stop.flag ab, und die Warteschleife des Messskripts bricht darauf ab. 2. ZWEITES TELEFON. Der Beobachter las immer schon beide Geraete, hielt die Zahlen aber nur im Speicher fuer die Anzeige. Da das S22 per Automatik immer auf dem GEGEN-AP sitzt, fehlte damit ausgerechnet die Strecke, die die Alltagsabdeckung zeigt -- der Terrassen-Vergleich war nicht zu fuehren. Jetzt: zweiter Ping (walk-ping-iphone.csv) und beide-telefone.csv im 2-s-Takt mit iface + Signal je Geraet. Beim Testen kamen zwei Fehler ans Licht, die den naechsten Lauf gekostet haetten: - `PINGER=$(ping_lauf ...)` blockiert. Die Kommandosubstitution wartet, bis die stdout-Pipe schliesst, und der Hintergrundjob darin haelt sie offen. Das Skript stand in dieser Zeile, der zweite Ping wurde nie gestartet -- und es sah von aussen aus wie ein normal laufender Lauf. Die Funktion laeuft in der aktuellen Shell, also liefert $! danach die richtige PID. - `kill $SAMPLER` traf nur den Wrapper. Dessen Subshell samt SSH-Sitzung wurde dabei verwaist und lief weiter: nach dem Stopp hielt der Core stumm eine Sampler-Sitzung offen. Wer den Vater zuerst killt, verliert den Zugriff auf die Kinder -- jetzt killbaum(), Kinder zuerst. Mitgenommen von der Rotationsliste: tp6-monitor-core.sh und der Ping in tp25-walk-messung.sh laufen jetzt ueber `sshpass -e` statt `-p`. Damit steht das Router-Passwort in keiner Kommandozeile mehr. `pgrep -fl "sshpass -p"` ist leer. Offen bleibt tp25-pin-s22.sh. Abnahme: Lauf gestartet, beide Ziele gepingt (10.40.10.178 + .196), ein Klick auf den Stopp-Knopf, danach kein Prozess und keine SSH-Sitzung mehr uebrig, Pin geloest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
99 lines
4.3 KiB
Bash
Executable File
99 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# TP6 — Core-Sampler (read-only)
|
|
#
|
|
# Haengt EINE persistente SSH-Sitzung an crs326-core und laesst dort eine Console-Schleife
|
|
# laufen, die im festen Takt eine CSV-Zeile ausgibt: Core-CPU, WAN-Rate auf vlan100 und
|
|
# — optional — die Registration-Table-Werte EINES WLAN-Clients.
|
|
#
|
|
# 🔴 Ausschliesslich Lesezugriffe (get / find / monitor-traffic once). Kein Write, kein
|
|
# /system script, kein /system logging. Aendert nichts am Netz.
|
|
#
|
|
# 🔴 Unter CAPsMAN fuehrt der MANAGER die Registration-Table — deshalb wird der CORE
|
|
# abgefragt und nicht ap1/ap2, wo die Tabelle leer waere.
|
|
#
|
|
# Aufruf:
|
|
# bash docs/tp6-monitor-core.sh --out /pfad/sampler.csv # nur CPU/WAN
|
|
# bash docs/tp6-monitor-core.sh --out /pfad/sampler.csv --mac F2:62:4C:E1:AF:09
|
|
#
|
|
# Beenden: Ctrl-C (oder kill auf die PID).
|
|
|
|
set -uo pipefail
|
|
|
|
MAC=""
|
|
INTERVAL=2
|
|
OUT=""
|
|
ROUTER_IP="10.40.99.1"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--mac) MAC="${2:-}"; shift 2 ;;
|
|
--interval) INTERVAL="${2:-2}"; shift 2 ;;
|
|
--out) OUT="${2:-}"; shift 2 ;;
|
|
--ip) ROUTER_IP="${2:-}"; shift 2 ;;
|
|
*) echo "unbekanntes Argument: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
[[ -n "$OUT" ]] || { echo "--out fehlt" >&2; exit 2; }
|
|
|
|
# Passwort aus dem Credential-Store. Wird NIE ausgegeben.
|
|
PW="$(grep -m1 '^CRS326_CORE_PASS=' ~/.secrets/credentials.env | cut -d= -f2- | sed 's/^["'"'"']//; s/["'"'"']$//')"
|
|
[[ -n "$PW" ]] || { echo "CRS326_CORE_PASS nicht in ~/.secrets/credentials.env gefunden" >&2; exit 1; }
|
|
|
|
# RouterOS-Schleife. Platzhalter werden unten ersetzt (RouterOS nutzt $ selbst, daher kein
|
|
# Shell-Interpolieren im Schleifenkoerper).
|
|
read -r -d '' ROS <<'ROS_EOF'
|
|
:local m "__MAC__";
|
|
:while (true) do={
|
|
:local cpu [/system resource get cpu-load];
|
|
:local w [/interface monitor-traffic vlan100 once as-value];
|
|
:local line ([/system clock get time] . "," . $cpu . "," . ($w->"rx-bits-per-second") . "," . ($w->"tx-bits-per-second"));
|
|
:if ([:len $m] > 0) do={
|
|
:local id [/interface/wifi/registration-table find where mac-address=$m];
|
|
:if ([:len $id] = 0) do={
|
|
:set line ($line . ",absent,,,,,,");
|
|
} else={
|
|
:local r [/interface/wifi/registration-table get [:pick $id 0]];
|
|
:set line ($line . "," . ($r->"interface") . "," . ($r->"signal") . "," . ($r->"tx-rate") . "," . ($r->"rx-rate") . "," . ($r->"tx-bits-per-second") . "," . ($r->"rx-bits-per-second") . "," . ($r->"uptime") . "," . ($r->"last-activity"));
|
|
};
|
|
};
|
|
:put $line;
|
|
:delay __DELAY__s;
|
|
}
|
|
ROS_EOF
|
|
|
|
ROS="${ROS//__MAC__/$MAC}"
|
|
ROS="${ROS//__DELAY__/$INTERVAL}"
|
|
# 🔴 Die RouterOS-Console parst eine per SSH uebergebene Mehrzeilen-Eingabe ZEILENWEISE
|
|
# ("expected closing brace"). Das Skript muss deshalb als EINE Zeile ankommen —
|
|
# und jeder do={}-Block braucht dann ein abschliessendes ";", sonst kommt
|
|
# "expected end of command".
|
|
ROS="$(printf '%s' "$ROS" | tr '\n' ' ')"
|
|
|
|
echo "ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity" > "$OUT"
|
|
|
|
echo "Sampler laeuft -> $OUT (Takt ${INTERVAL}s${MAC:+, Client $MAC})"
|
|
|
|
# Lokaler Zeitstempel beim Eintreffen der Zeile. Bewusst kein awk: das BSD-awk auf macOS
|
|
# kennt systime()/strftime() nicht (das ist gawk).
|
|
#
|
|
# 🔴 Mit Reconnect-Schleife: die SSH-Sitzung ist am 2026-08-21 mitten in einer Gehweg-Messung
|
|
# weggebrochen ("Can't assign requested address"), und die Funkdaten endeten 2,5 Minuten vor
|
|
# dem Ping-Mitschnitt — ausgerechnet im interessanten Teil. Ein Sampler, der still stirbt,
|
|
# ist schlimmer als keiner.
|
|
while true; do
|
|
# 🔴 -e statt -p: mit -p steht das Router-Passwort in der Kommandozeile und damit in `ps`
|
|
# und in jedem Prozess-Trace. Am 2026-08-22 ist es so im Klartext in einen Mitschnitt
|
|
# geraten. Mit -e liegt es nur in der Umgebung dieses Kindprozesses.
|
|
SSHPASS="$PW" sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 \
|
|
-o ServerAliveInterval=15 -o ServerAliveCountMax=3 "admin@${ROUTER_IP}" "$ROS" \
|
|
2>>"${OUT%.csv}.stderr.log" \
|
|
| while IFS= read -r line; do
|
|
printf '%s,%s,%s\n' "$(date +%s)" "$(date +%H:%M:%S)" "$line" >> "$OUT"
|
|
done
|
|
printf '%s,%s,RECONNECT\n' "$(date +%s)" "$(date +%H:%M:%S)" >> "$OUT"
|
|
echo "$(date +%H:%M:%S) Verbindung weg -- neuer Versuch in 2 s" >> "${OUT%.csv}.stderr.log"
|
|
sleep 2
|
|
done
|