native-macos: Downloads-Bibliothek des Docker-Tools als zweite Quelle nutzbar machen

- Neuer Auswahlschritt: Apple-Server (Download) vs. lokale downloads/library
  (Docker-Tool) -- letzteres komplett offline nutzbar.
- InstallAssistant.pkg (Big Sur+) wird per installer -pkg -target / zur
  vollstaendigen Install-App entpackt, danach normaler
  createinstallmedia-Weg.
- BaseSystem.dmg/InstallESD.dmg (bis Catalina) ist bereits ein fertiges
  bootfaehiges Volume -- kein createinstallmedia noetig, stattdessen
  diskutil eraseDisk + asr restore --erase (etablierte Community-Technik).
- Flat-JSON-Parser (sed) fuer meta.json ohne jq/python3-Abhaengigkeit.
- Auswahl-/Verzweigungslogik unter Linux mit simulierter Bibliothek
  end-to-end durchgetestet (beide Modi laufen korrekt bis zum jeweils
  ersten macOS-only-Befehl).
This commit is contained in:
ARIA
2026-07-18 12:04:03 +02:00
parent e4dd003bd6
commit 0d0c137de3
2 changed files with 415 additions and 161 deletions
+335 -117
View File
@@ -1,25 +1,37 @@
#!/bin/bash
#
# create-stick.sh — natives macOS-Terminal-Tool fuer bootfaehige
# Installer-Sticks via Apples eigenem createinstallmedia.
#
# Laeuft NUR auf echtem macOS (10.15 Catalina oder neuer). Nutzt
# ausschliesslich Bordmittel: softwareupdate, diskutil, PlistBuddy,
# Installer-Sticks. Laeuft NUR auf echtem macOS. Nutzt ausschliesslich
# Bordmittel: softwareupdate, diskutil, PlistBuddy, installer, asr,
# createinstallmedia. Kein Homebrew, keine externen Abhaengigkeiten.
#
# Warum ein eigener Pfad neben dem Docker/Linux-Tool im Projekt-Root:
# Das Docker-Tool zieht rohe Katalog-Images (BaseSystem.dmg bzw.
# InstallAssistant.pkg) und schreibt sie per dd — das funktioniert ohne
# Mac, aber createinstallmedia braucht die VOLLSTAENDIGE "Install macOS
# X.app", nicht die rohen Katalog-Dateien. Der offizielle, von Apple
# unterstuetzte Weg an diese App zu kommen OHNE App Store ist
# `softwareupdate --fetch-full-installer`. Deshalb ist dieses Script
# bewusst komplett unabhaengig vom ./downloads/library-Ordner des
# Docker-Tools — beide Formate sind nicht kompatibel zueinander.
# Zwei moegliche QUELLEN fuer den Installer-Payload:
#
# Zukunftssicherheit: `softwareupdate --list-full-installers` fragt
# Apples eigene Server live ab. Neue macOS-Versionen tauchen automatisch
# auf, ohne dass dieses Script angefasst werden muss.
# 1) Apple-Server (Download)
# softwareupdate --fetch-full-installer laedt die komplette
# "Install macOS X.app" direkt von Apple. Danach normaler
# createinstallmedia-Weg. Zukunftssicher: die Versionsliste kommt
# live von Apples eigenen Servern, neue macOS-Versionen tauchen
# automatisch auf.
#
# 2) Lokale Downloads-Bibliothek des Docker/Linux-Tools
# (../downloads/library relativ zu diesem Script, wenn das ganze
# Projekt inkl. Downloads z.B. per externer Platte auf den Mac
# kopiert wurde). Kein Internet noetig, kein erneuter Download.
# Zwei Payload-Formate stecken dort je nach macOS-Version, beide
# werden hier unterstuetzt:
# - InstallAssistant.pkg (Big Sur+): 'installer -pkg ... -target /'
# entpackt daraus die komplette Install-App (inkl.
# createinstallmedia-Binary) nach /Applications -- danach der
# normale createinstallmedia-Weg wie bei Quelle 1.
# - BaseSystem.dmg/InstallESD.dmg (bis Catalina): das ist schon
# ein fertiges, bootfaehiges Volume. createinstallmedia braucht
# es nicht extra -- Apples eigenes 'asr restore' schreibt es
# direkt auf den Stick. Kein App-Download noetig.
#
# So wird aus jeder bereits vom Docker-Tool gebauten Offline-Bibliothek
# (externe Platte, ohne Internet) auch am echten Mac ein bootfaehiger
# Stick, ganz ohne doppelten Download.
set -u
@@ -37,112 +49,276 @@ err() { printf "%s%s%s\n" "$RED" "FEHLER: $1" "$RESET" >&2; }
ok() { printf "%s%s%s\n" "$GREEN" "$1" "$RESET"; }
warn() { printf "%s%s%s\n" "$YELLOW" "$1" "$RESET"; }
# Sehr simpler Flat-JSON-Feld-Extraktor -- reicht fuer die meta.json-Dateien
# der Bibliothek (keine verschachtelten Objekte), spart eine Abhaengigkeit
# zu jq/python3 die auf einem frischen Mac nicht garantiert vorhanden ist.
json_field() {
local file="$1" key="$2"
sed -n 's/.*"'"$key"'":[[:space:]]*"\{0,1\}\([^",}]*\)"\{0,1\}.*/\1/p' "$file" | head -n1
}
# ---------- Vorpruefungen ----------
if [[ "$(uname)" != "Darwin" ]]; then
err "Dieses Script laeuft nur auf echtem macOS (kein Linux, keine VM ohne macOS)."
exit 1
fi
if ! command -v softwareupdate >/dev/null 2>&1; then
err "'softwareupdate' nicht gefunden — ungewoehnliches macOS-Setup, Abbruch."
exit 1
fi
# ---------- Schritt 1: Quelle + Version waehlen ----------
title "macOS USB-Stick-Creator (nativ) — Schritt 1/4: Quelle + Version"
MACOS_VER="$(sw_vers -productVersion)"
# fetch-full-installer gibt es erst ab Catalina (10.15)
if [[ "$MACOS_VER" == 10.* ]]; then
MINOR="${MACOS_VER#10.}"
MINOR="${MINOR%%.*}"
if [[ "$MINOR" -lt 15 ]]; then
err "macOS ${MACOS_VER} erkannt — 'softwareupdate --fetch-full-installer' braucht mind. Catalina (10.15)."
exit 1
fi
fi
# ---------- Schritt 1: verfuegbare Installer laden ----------
title "macOS USB-Stick-Creator (nativ) — Schritt 1/4: Verfuegbare Versionen"
echo "Frage Apples Software-Update-Server nach verfuegbaren kompletten Installern ab..."
echo "Woher soll der macOS-Installer kommen?"
echo
LIST_RAW="$(softwareupdate --list-full-installers 2>/dev/null)"
if [[ -z "$LIST_RAW" ]] || ! grep -q "Title:" <<<"$LIST_RAW"; then
err "Keine Installer gefunden. Internetverbindung pruefen, oder Apple hat gerade ein Problem."
exit 1
fi
# Zeilenformat: "* Title: macOS Sonoma, Version: 14.6.1, Size: 12345678900, Build: 23G93"
declare -a TITLES=()
declare -a VERSIONS=()
while IFS= read -r line; do
[[ "$line" == *"Title:"* ]] || continue
t="$(sed -E 's/^\* Title: ([^,]+),.*/\1/' <<<"$line")"
v="$(sed -E 's/.*Version: ([^,]+),.*/\1/' <<<"$line")"
TITLES+=("$t")
VERSIONS+=("$v")
done <<<"$LIST_RAW"
if [[ ${#TITLES[@]} -eq 0 ]]; then
err "Konnte die Liste nicht parsen. Rohausgabe:"
echo "$LIST_RAW"
exit 1
fi
echo "Verfuegbar:"
echo
for i in "${!TITLES[@]}"; do
printf " %s%2d)%s %s (%s)\n" "$BOLD" "$((i+1))" "$RESET" "${TITLES[$i]}" "${VERSIONS[$i]}"
done
echo " ${BOLD}1)${RESET} Von Apple herunterladen (braucht Internet, mehrere GB)"
echo " ${BOLD}2)${RESET} Aus lokaler Downloads-Bibliothek (Docker-Tool) verwenden -- kein Internet noetig"
echo
printf "%s0)%s Abbrechen\n" "$BOLD" "$RESET"
echo
read -r -p "Welche Version soll heruntergeladen/benutzt werden? [Nummer]: " CHOICE
read -r -p "Quelle waehlen [Nummer]: " SRC_CHOICE
if [[ "$CHOICE" == "0" || -z "$CHOICE" ]]; then
if [[ "$SRC_CHOICE" == "0" || -z "$SRC_CHOICE" ]]; then
echo "Abgebrochen."
exit 0
fi
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || (( CHOICE < 1 || CHOICE > ${#TITLES[@]} )); then
err "Ungueltige Auswahl."
exit 1
fi
SEL_TITLE="${TITLES[$((CHOICE-1))]}"
SEL_VERSION="${VERSIONS[$((CHOICE-1))]}"
# Apples Titel-Feld liefert z.B. "macOS Sonoma" -> App heisst "Install macOS Sonoma.app"
APP_PATH="/Applications/Install ${SEL_TITLE}.app"
SOURCE=""
WRITE_MODE="" # "cim" (createinstallmedia) oder "asr" (direktes Image-Restore)
APP_PATH=""
DMG_PATH=""
LIB_TITLE=""
LIB_VERSION=""
echo
ok "Gewaehlt: ${SEL_TITLE} (${SEL_VERSION})"
case "$SRC_CHOICE" in
1)
SOURCE="apple"
;;
2)
SOURCE="library"
;;
*)
err "Ungueltige Auswahl."
exit 1
;;
esac
# ---------- Schritt 2: Download (falls noetig) ----------
title "Schritt 2/4: Installer-App besorgen"
if [[ "$SOURCE" == "apple" ]]; then
if ! command -v softwareupdate >/dev/null 2>&1; then
err "'softwareupdate' nicht gefunden — ungewoehnliches macOS-Setup, Abbruch."
exit 1
fi
if [[ -d "$APP_PATH" ]]; then
ok "'${APP_PATH}' existiert bereits — Download wird uebersprungen."
else
warn "Das laedt mehrere GB von Apple und braucht sudo-Rechte."
echo "Zielort: ${APP_PATH}"
read -r -p "Download jetzt starten? [j/N]: " GO
if [[ ! "$GO" =~ ^[jJ]$ ]]; then
MACOS_VER="$(sw_vers -productVersion)"
# fetch-full-installer gibt es erst ab Catalina (10.15)
if [[ "$MACOS_VER" == 10.* ]]; then
MINOR="${MACOS_VER#10.}"
MINOR="${MINOR%%.*}"
if [[ "$MINOR" -lt 15 ]]; then
err "macOS ${MACOS_VER} erkannt — 'softwareupdate --fetch-full-installer' braucht mind. Catalina (10.15)."
exit 1
fi
fi
echo
echo "Frage Apples Software-Update-Server nach verfuegbaren kompletten Installern ab..."
echo
LIST_RAW="$(softwareupdate --list-full-installers 2>/dev/null)"
if [[ -z "$LIST_RAW" ]] || ! grep -q "Title:" <<<"$LIST_RAW"; then
err "Keine Installer gefunden. Internetverbindung pruefen, oder Apple hat gerade ein Problem."
exit 1
fi
# Zeilenformat: "* Title: macOS Sonoma, Version: 14.6.1, Size: 12345678900, Build: 23G93"
declare -a TITLES=()
declare -a VERSIONS=()
while IFS= read -r line; do
[[ "$line" == *"Title:"* ]] || continue
t="$(sed -E 's/^\* Title: ([^,]+),.*/\1/' <<<"$line")"
v="$(sed -E 's/.*Version: ([^,]+),.*/\1/' <<<"$line")"
TITLES+=("$t")
VERSIONS+=("$v")
done <<<"$LIST_RAW"
if [[ ${#TITLES[@]} -eq 0 ]]; then
err "Konnte die Liste nicht parsen. Rohausgabe:"
echo "$LIST_RAW"
exit 1
fi
echo "Verfuegbar:"
echo
for i in "${!TITLES[@]}"; do
printf " %s%2d)%s %s (%s)\n" "$BOLD" "$((i+1))" "$RESET" "${TITLES[$i]}" "${VERSIONS[$i]}"
done
echo
printf "%s0)%s Abbrechen\n" "$BOLD" "$RESET"
echo
read -r -p "Welche Version soll heruntergeladen/benutzt werden? [Nummer]: " CHOICE
if [[ "$CHOICE" == "0" || -z "$CHOICE" ]]; then
echo "Abgebrochen."
exit 0
fi
echo
echo "Starte Download (kann je nach Version 30-90 Minuten dauern)..."
sudo softwareupdate --fetch-full-installer --full-installer-version "$SEL_VERSION"
RC=$?
if [[ $RC -ne 0 || ! -d "$APP_PATH" ]]; then
err "Download fehlgeschlagen oder App nicht am erwarteten Ort. Erwartet: ${APP_PATH}"
echo "Tipp: 'ls /Applications | grep Install' zeigt den tatsaechlichen Namen."
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || (( CHOICE < 1 || CHOICE > ${#TITLES[@]} )); then
err "Ungueltige Auswahl."
exit 1
fi
ok "Download abgeschlossen: ${APP_PATH}"
SEL_TITLE="${TITLES[$((CHOICE-1))]}"
SEL_VERSION="${VERSIONS[$((CHOICE-1))]}"
WRITE_MODE="cim"
# Apples Titel-Feld liefert z.B. "macOS Sonoma" -> App heisst "Install macOS Sonoma.app"
APP_PATH="/Applications/Install ${SEL_TITLE}.app"
echo
ok "Gewaehlt: ${SEL_TITLE} (${SEL_VERSION}) -- Quelle: Apple-Server"
else
echo
DEFAULT_LIB_DIR="$(cd "$(dirname "$0")/.." 2>/dev/null && pwd)/downloads/library"
echo "Pfad zur lokalen Downloads-Bibliothek des Docker-Tools (Ordner mit einem"
echo "Unterordner pro macOS-Version, je mit meta.json + Installer-Datei)."
echo
read -r -p "Pfad [Enter fuer ${DEFAULT_LIB_DIR}]: " LIB_DIR
LIB_DIR="${LIB_DIR:-$DEFAULT_LIB_DIR}"
if [[ ! -d "$LIB_DIR" ]]; then
err "Ordner nicht gefunden: ${LIB_DIR}"
exit 1
fi
declare -a LIB_ENTRY_DIRS=()
declare -a LIB_ENTRY_DESC=()
for entry_dir in "$LIB_DIR"/*/; do
[[ -d "$entry_dir" ]] || continue
meta="${entry_dir}meta.json"
[[ -f "$meta" ]] || continue
complete="$(json_field "$meta" complete)"
[[ "$complete" == "true" ]] || continue
et="$(json_field "$meta" title)"
ev="$(json_field "$meta" version)"
emode="$(json_field "$meta" mode)"
esize="$(json_field "$meta" size_bytes)"
esize_gb="?"
if [[ "$esize" =~ ^[0-9]+$ ]]; then
esize_gb="$(( esize / 1000 / 1000 / 1000 ))"
fi
mode_desc="bis Catalina, robust"
[[ "$emode" == "recovery" ]] && mode_desc="Big Sur+, ueber installer-pkg"
LIB_ENTRY_DIRS+=("$entry_dir")
LIB_ENTRY_DESC+=("${et} (${ev}) -- ~${esize_gb} GB, ${mode_desc}")
done
if [[ ${#LIB_ENTRY_DIRS[@]} -eq 0 ]]; then
err "Keine vollstaendigen Installer in ${LIB_DIR} gefunden."
exit 1
fi
echo
echo "In der Bibliothek gefunden:"
echo
for i in "${!LIB_ENTRY_DIRS[@]}"; do
printf " %s%2d)%s %s\n" "$BOLD" "$((i+1))" "$RESET" "${LIB_ENTRY_DESC[$i]}"
done
echo
printf "%s0)%s Abbrechen\n" "$BOLD" "$RESET"
echo
read -r -p "Welche Version verwenden? [Nummer]: " LCHOICE
if [[ "$LCHOICE" == "0" || -z "$LCHOICE" ]]; then
echo "Abgebrochen."
exit 0
fi
if ! [[ "$LCHOICE" =~ ^[0-9]+$ ]] || (( LCHOICE < 1 || LCHOICE > ${#LIB_ENTRY_DIRS[@]} )); then
err "Ungueltige Auswahl."
exit 1
fi
SEL_ENTRY_DIR="${LIB_ENTRY_DIRS[$((LCHOICE-1))]}"
SEL_META="${SEL_ENTRY_DIR}meta.json"
LIB_TITLE="$(json_field "$SEL_META" title)"
LIB_VERSION="$(json_field "$SEL_META" version)"
LIB_MODE="$(json_field "$SEL_META" mode)"
LIB_FILENAME="$(json_field "$SEL_META" filename)"
LIB_PAYLOAD_PATH="${SEL_ENTRY_DIR}${LIB_FILENAME}"
if [[ ! -f "$LIB_PAYLOAD_PATH" ]]; then
err "Payload-Datei nicht gefunden: ${LIB_PAYLOAD_PATH}"
exit 1
fi
if [[ "$LIB_MODE" == "recovery" ]]; then
WRITE_MODE="cim"
else
WRITE_MODE="asr"
DMG_PATH="$LIB_PAYLOAD_PATH"
fi
echo
ok "Gewaehlt: ${LIB_TITLE} (${LIB_VERSION}) -- Quelle: lokale Bibliothek (${LIB_PAYLOAD_PATH})"
fi
CIM_BIN="${APP_PATH}/Contents/Resources/createinstallmedia"
if [[ ! -x "$CIM_BIN" ]]; then
err "createinstallmedia nicht gefunden unter: ${CIM_BIN}"
exit 1
# ---------- Schritt 2: Installer-Payload besorgen ----------
title "Schritt 2/4: Installer-Payload besorgen"
if [[ "$SOURCE" == "apple" ]]; then
if [[ -d "$APP_PATH" ]]; then
ok "'${APP_PATH}' existiert bereits — Download wird uebersprungen."
else
warn "Das laedt mehrere GB von Apple und braucht sudo-Rechte."
echo "Zielort: ${APP_PATH}"
read -r -p "Download jetzt starten? [j/N]: " GO
if [[ ! "$GO" =~ ^[jJ]$ ]]; then
echo "Abgebrochen."
exit 0
fi
echo
echo "Starte Download (kann je nach Version 30-90 Minuten dauern)..."
sudo softwareupdate --fetch-full-installer --full-installer-version "$SEL_VERSION"
RC=$?
if [[ $RC -ne 0 || ! -d "$APP_PATH" ]]; then
err "Download fehlgeschlagen oder App nicht am erwarteten Ort. Erwartet: ${APP_PATH}"
echo "Tipp: 'ls /Applications | grep Install' zeigt den tatsaechlichen Namen."
exit 1
fi
ok "Download abgeschlossen: ${APP_PATH}"
fi
elif [[ "$WRITE_MODE" == "cim" ]]; then
# Bibliothek, Big Sur+: InstallAssistant.pkg -> komplette Install-App
# nach /Applications entpacken (Apples Standardverhalten von 'installer').
if [[ -d "$APP_PATH" ]]; then
ok "'${APP_PATH}' existiert bereits — Installer-Lauf wird uebersprungen."
else
echo "Entpacke ${LIB_PAYLOAD_PATH} nach /Applications (installer -pkg, braucht sudo)..."
echo "Das dauert je nach Groesse ein paar Minuten."
echo
sudo installer -pkg "$LIB_PAYLOAD_PATH" -target /
RC=$?
if [[ $RC -ne 0 ]]; then
err "'installer -pkg' fehlgeschlagen ($RC)."
exit 1
fi
if [[ ! -d "$APP_PATH" ]]; then
# Fallback: Apples interner App-Name wich vom Bibliotheks-Titel ab --
# nimm das zuletzt angelegte "Install macOS *.app"-Bundle.
FALLBACK_APP="$(ls -dt /Applications/Install\ macOS*.app 2>/dev/null | head -n1)"
[[ -n "$FALLBACK_APP" ]] && APP_PATH="$FALLBACK_APP"
fi
if [[ ! -d "$APP_PATH" ]]; then
err "Konnte die installierte App nach 'installer -pkg' nicht finden."
echo "Tipp: 'ls /Applications | grep Install' zeigt was tatsaechlich da ist."
exit 1
fi
ok "Installiert: ${APP_PATH}"
fi
else
ok "Bibliothek liefert bereits ein fertiges, bootfaehiges Image (${DMG_PATH}) -- kein App-Download noetig."
fi
if [[ "$WRITE_MODE" == "cim" ]]; then
CIM_BIN="${APP_PATH}/Contents/Resources/createinstallmedia"
if [[ ! -x "$CIM_BIN" ]]; then
err "createinstallmedia nicht gefunden unter: ${CIM_BIN}"
exit 1
fi
fi
# ---------- Schritt 3: Ziel-USB-Stick waehlen ----------
@@ -209,33 +385,75 @@ if [[ "$CONFIRM" != "/dev/${TARGET_DISK}" ]]; then
exit 1
fi
# ---------- Schritt 4: createinstallmedia ausfuehren ----------
# ---------- Schritt 4: Stick schreiben ----------
title "Schritt 4/4: Stick wird erstellt"
echo "App: ${APP_PATH}"
echo "Ziel: /dev/${TARGET_DISK}"
echo
echo "createinstallmedia laeuft jetzt (braucht sudo, dauert typischerweise 10-30 Minuten)..."
echo "Der Stick wird zwischendurch umbenannt/neu gemountet — das ist normal."
echo
if [[ "$WRITE_MODE" == "cim" ]]; then
echo "App: ${APP_PATH}"
echo "Ziel: /dev/${TARGET_DISK}"
echo
echo "createinstallmedia laeuft jetzt (braucht sudo, dauert typischerweise 10-30 Minuten)..."
echo "Der Stick wird zwischendurch umbenannt/neu gemountet — das ist normal."
echo
sudo "$CIM_BIN" --volume "/dev/${TARGET_DISK}" --nointeraction
RC=$?
sudo "$CIM_BIN" --volume "/dev/${TARGET_DISK}" --nointeraction
RC=$?
echo
if [[ $RC -eq 0 ]]; then
ok "Fertig! Der Stick ist bootfaehig."
echo "Am Ziel-Mac: beim Start Option/Alt gedrueckt halten, den Stick im Boot-Picker waehlen."
echo
if [[ $RC -eq 0 ]]; then
ok "Fertig! Der Stick ist bootfaehig."
echo "Am Ziel-Mac: beim Start Option/Alt gedrueckt halten, den Stick im Boot-Picker waehlen."
else
err "createinstallmedia ist mit Fehlercode ${RC} beendet — siehe Ausgabe oben."
exit $RC
fi
echo
read -r -p "Die installierte App (mehrere GB) jetzt wieder loeschen um Platz zu sparen? [j/N]: " CLEAN
if [[ "$CLEAN" =~ ^[jJ]$ ]]; then
sudo rm -rf "$APP_PATH"
ok "Geloescht: ${APP_PATH}"
fi
else
err "createinstallmedia ist mit Fehlercode ${RC} beendet — siehe Ausgabe oben."
exit $RC
fi
# asr-Pfad: BaseSystem.dmg/InstallESD.dmg ist schon ein fertiges,
# bootfaehiges Volume. Erst Stick neu formatieren (liefert einen
# Mountpunkt), dann Apples 'asr restore' das eigentliche Image drauf
# kopieren lassen -- das re-formatiert dabei nochmal komplett nach dem
# Schema des Quell-Images (--erase). Etablierte Community-Technik fuer
# macOS-Installer bis Catalina ohne createinstallmedia.
echo "Quelle: ${DMG_PATH}"
echo "Ziel: /dev/${TARGET_DISK}"
echo
echo "Formatiere /dev/${TARGET_DISK} neu (HFS+) als Vorbereitung (braucht sudo)..."
sudo diskutil eraseDisk JHFS+ INSTALL "/dev/${TARGET_DISK}"
if [[ $? -ne 0 ]]; then
err "diskutil eraseDisk fehlgeschlagen."
exit 1
fi
echo
read -r -p "Die heruntergeladene Installer-App (mehrere GB) jetzt loeschen um Platz zu sparen? [j/N]: " CLEAN
if [[ "$CLEAN" =~ ^[jJ]$ ]]; then
sudo rm -rf "$APP_PATH"
ok "Geloescht: ${APP_PATH}"
VOL_MOUNT="/Volumes/INSTALL"
if [[ ! -d "$VOL_MOUNT" ]]; then
err "Erwarteter Mountpunkt ${VOL_MOUNT} nicht gefunden nach dem Formatieren."
echo "Tipp: 'diskutil list /dev/${TARGET_DISK}' zeigt den tatsaechlichen Zustand."
exit 1
fi
echo
echo "asr restore laeuft jetzt (braucht sudo, dauert typischerweise 10-20 Minuten)..."
echo "Der Stick wird dabei nochmal komplett neu formatiert -- das ist normal."
echo
sudo asr restore --source "$DMG_PATH" --target "$VOL_MOUNT" --erase --noprompt
RC=$?
echo
if [[ $RC -eq 0 ]]; then
ok "Fertig! Der Stick ist bootfaehig."
echo "Am Ziel-Mac: beim Start Option/Alt gedrueckt halten, den Stick im Boot-Picker waehlen."
else
err "asr restore ist mit Fehlercode ${RC} beendet — siehe Ausgabe oben."
exit $RC
fi
fi
echo