#!/bin/sh # Стабильный URL для Joplin на телефоне: http://.local:8080 # Не зависит от подсети хотспота (10.219.x → 10.74.x). Alias *.100 не нужен. # # ./joplin-mdns-setup.sh status # ./joplin-mdns-setup.sh install # записать URL в env (rename опционально) # ./joplin-mdns-setup.sh verify set -e CONFIG="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}" PORT="${JOPLIN_WEBDAV_PORT:-8080}" WIFI_DEV="${WIFI_DEVICE:-en0}" # Пусто = текущий LocalHostName Mac (у вас часто Eternals → eternals.local) PREFERRED_HOST="${JOPLIN_MDNS_HOST:-}" load_config() { if [ -f "$CONFIG" ]; then # shellcheck disable=SC1090 . "$CONFIG" fi PORT="${JOPLIN_WEBDAV_PORT:-$PORT}" PREFERRED_HOST="${JOPLIN_MDNS_HOST:-$PREFERRED_HOST}" } current_local_hostname() { scutil --get LocalHostName 2>/dev/null || true } mdns_host() { load_config if [ -n "$PREFERRED_HOST" ]; then printf '%s\n' "$PREFERRED_HOST" else current_local_hostname fi } mdns_fqdn() { printf '%s.local\n' "$(mdns_host | tr '[:upper:]' '[:lower:]')" } phone_url() { host="$(mdns_host | tr '[:upper:]' '[:lower:]')" printf 'http://%s.local:%s\n' "$host" "$PORT" } primary_ip() { ipconfig getifaddr "$WIFI_DEV" 2>/dev/null || true } resolve_mdns_ip() { host="$(mdns_fqdn)" dscacheutil -q host -a name "$host" 2>/dev/null \ | awk '/ip_address:/ {print $2}' | grep -v '^127\.' | head -1 } cmd_status() { load_config local_name="$(current_local_hostname)" host="$(mdns_host)" ip="$(primary_ip)" resolved="$(resolve_mdns_ip 2>/dev/null || true)" url="$(phone_url)" echo "LocalHostName: ${local_name:-?}" echo "mDNS host: $host → $(mdns_fqdn)" echo "primary $WIFI_DEV: ${ip:-(none)}" echo "mDNS → IP: ${resolved:-(none)}" echo "" echo "mDNS URL (НЕ для Android-хотспота — телефон не резолвит .local клиентов):" echo " $url" echo "URL на Mac: http://127.0.0.1:${PORT}" echo "Телефон-хотспот: ./joplin-hotspot-alias.sh status" if [ -n "$PREFERRED_HOST" ] && [ "$local_name" != "$PREFERRED_HOST" ]; then echo "" echo "⚠ В env JOPLIN_MDNS_HOST=$PREFERRED_HOST, LocalHostName=$local_name" echo " install переименует Mac или уберите JOPLIN_MDNS_HOST из env" elif [ -n "$ip" ] && [ -n "$resolved" ] && [ "$ip" = "$resolved" ]; then echo "" echo "OK: mDNS на Mac резолвится (для телефона используйте alias *.100)" elif [ -n "$ip" ] && [ -z "$resolved" ]; then echo "" echo "⚠ mDNS пока не резолвится — подождите или переподключите Wi‑Fi" elif [ -z "$ip" ]; then echo "" echo "⚠ Нет IP на $WIFI_DEV" fi } write_env_mdns() { load_config url="$(phone_url)" host="$(mdns_host)" if [ ! -f "$CONFIG" ]; then echo "Нет $CONFIG — сначала joplin-webdav-install.sh" >&2 return 1 fi if grep -q '^JOPLIN_MDNS_HOST=' "$CONFIG" 2>/dev/null; then sed -i '' "s|^JOPLIN_MDNS_HOST=.*|JOPLIN_MDNS_HOST=$host|" "$CONFIG" 2>/dev/null \ || sed -i "s|^JOPLIN_MDNS_HOST=.*|JOPLIN_MDNS_HOST=$host|" "$CONFIG" else printf 'JOPLIN_MDNS_HOST=%s\n' "$host" >>"$CONFIG" fi if grep -q '^JOPLIN_PHONE_URL=' "$CONFIG" 2>/dev/null; then sed -i '' "s|^JOPLIN_PHONE_URL=.*|JOPLIN_PHONE_URL=$url|" "$CONFIG" 2>/dev/null \ || sed -i "s|^JOPLIN_PHONE_URL=.*|JOPLIN_PHONE_URL=$url|" "$CONFIG" else printf 'JOPLIN_PHONE_URL=%s\n' "$url" >>"$CONFIG" fi } cmd_install() { load_config local_name="$(current_local_hostname)" target="$(mdns_host)" if [ -n "$PREFERRED_HOST" ] && [ "$local_name" != "$PREFERRED_HOST" ]; then echo "Переименование LocalHostName: $local_name → $PREFERRED_HOST" if [ "$(id -u)" -eq 0 ]; then scutil --set LocalHostName "$PREFERRED_HOST" else sudo scutil --set LocalHostName "$PREFERRED_HOST" fi else echo "Используем текущий LocalHostName: $local_name (→ $(mdns_fqdn))" fi write_env_mdns echo "" echo "На телефоне в Joplin WebDAV (один раз):" echo " $(phone_url)" echo "" sleep 2 cmd_verify || true } cmd_verify() { ip="$(primary_ip)" resolved="$(resolve_mdns_ip 2>/dev/null || true)" if [ -z "$ip" ]; then echo "verify: нет IP на $WIFI_DEV" >&2 exit 1 fi if [ "$ip" = "$resolved" ]; then echo "verify OK: $(mdns_fqdn) → $ip" exit 0 fi echo "verify: mDNS=${resolved:-none} ip=$ip (часто OK через 30с после connect)" >&2 exit 1 } usage() { echo "Usage: $(basename "$0") status|install|verify" >&2 exit 1 } case "${1:-status}" in status) cmd_status ;; install) cmd_install ;; verify) cmd_verify ;; -h|--help) usage ;; *) usage ;; esac