sync-zshrc-all.sh
· 5.8 KiB · Bash
Исходник
#!/usr/bin/env bash
#
# sync-zshrc-all.sh - macOS Tahoe / Apple Silicon
#
# Menyinkronkan:
# 1. template .zshrc
# 2. /usr/local/etc/shell-prompt.zsh
# 3. config Fastfetch per-user
# 4. dependency Homebrew: vivid, fastfetch, coreutils, tree
#
# Jalankan sebagai USER ADMIN biasa, BUKAN dengan "sudo bash ...".
# Script akan meminta sudo hanya ketika diperlukan.
#
# Default: mengambil tiga file dari direktori yang sama dengan script ini.
# Untuk mode remote/Gist, isi URL melalui environment variable:
# ZSHRC_URL=https://... PROMPT_URL=https://... FASTFETCH_CONFIG_URL=https://... ./sync-zshrc-all.sh
set -euo pipefail
if [[ "$(uname -s)" != "Darwin" ]]; then
echo "Error: script ini hanya untuk macOS." >&2
exit 1
fi
if [[ "$(id -u)" -eq 0 ]]; then
echo "Jangan jalankan script ini sebagai root." >&2
echo "Jalankan sebagai user admin biasa: ./sync-zshrc-all.sh" >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOCAL_ZSHRC="$SCRIPT_DIR/zshrc"
LOCAL_PROMPT="$SCRIPT_DIR/shell-prompt.zsh"
LOCAL_FASTFETCH="$SCRIPT_DIR/config.jsonc"
ZSHRC_URL="${ZSHRC_URL:-}"
PROMPT_URL="${PROMPT_URL:-}"
FASTFETCH_CONFIG_URL="${FASTFETCH_CONFIG_URL:-}"
GLOBAL_ZSHRC_TEMPLATE="/usr/local/etc/zshrc-template"
PROMPT_FILE="/usr/local/etc/shell-prompt.zsh"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
need_cmd() {
command -v "$1" >/dev/null 2>&1
}
fetch_or_local() {
# fetch_or_local URL LOCAL_FILE DEST_TMP
local url="$1" local_file="$2" dest="$3"
if [[ -n "$url" ]]; then
if ! curl -fsSL "$url" -o "$dest"; then
echo "Error: gagal download $url" >&2
exit 1
fi
else
if [[ ! -f "$local_file" ]]; then
echo "Error: file lokal tidak ditemukan: $local_file" >&2
exit 1
fi
cp "$local_file" "$dest"
fi
}
sync_root_file() {
# sync_root_file SOURCE DEST LABEL MODE
local src="$1" dest="$2" label="$3" mode="$4"
if [[ ! -f "$dest" ]] || ! cmp -s "$src" "$dest"; then
sudo mkdir -p "$(dirname "$dest")"
sudo cp "$src" "$dest"
sudo chown root:wheel "$dest"
sudo chmod "$mode" "$dest"
echo " -> $label diperbarui."
else
echo " -> $label sudah sesuai, tidak ada perubahan."
fi
}
echo "== 0. Pastikan Homebrew tersedia =="
if ! need_cmd brew; then
echo "Error: Homebrew belum terinstall." >&2
echo "Install Homebrew terlebih dahulu dari https://brew.sh" >&2
exit 1
fi
eval "$(brew shellenv)"
echo
echo "== 1. Pastikan dependency terinstall =="
need_install=()
need_cmd vivid || need_install+=(vivid)
need_cmd fastfetch || need_install+=(fastfetch)
need_cmd gls || need_install+=(coreutils)
need_cmd tree || need_install+=(tree)
if (( ${#need_install[@]} > 0 )); then
echo " -> Menginstall: ${need_install[*]}"
brew install "${need_install[@]}"
else
echo " -> vivid, fastfetch, coreutils, tree sudah tersedia."
fi
echo
echo "== 2. Siapkan source file =="
tmp_zshrc="$TMP_DIR/zshrc"
tmp_prompt="$TMP_DIR/shell-prompt.zsh"
tmp_fastfetch="$TMP_DIR/config.jsonc"
fetch_or_local "$ZSHRC_URL" "$LOCAL_ZSHRC" "$tmp_zshrc"
fetch_or_local "$PROMPT_URL" "$LOCAL_PROMPT" "$tmp_prompt"
fetch_or_local "$FASTFETCH_CONFIG_URL" "$LOCAL_FASTFETCH" "$tmp_fastfetch"
echo " -> source file siap."
echo
echo "== 3. Sinkronkan template dan prompt global =="
sync_root_file "$tmp_zshrc" "$GLOBAL_ZSHRC_TEMPLATE" "$GLOBAL_ZSHRC_TEMPLATE" 644
sync_root_file "$tmp_prompt" "$PROMPT_FILE" "$PROMPT_FILE" 644
echo
echo "== 4. Terapkan .zshrc dan Fastfetch ke user manusia di /Users =="
while IFS=: read -r user _ uid _ _ home shell; do
# macOS human users umumnya UID >= 501. Skip system/shared/guest users.
(( uid >= 501 )) || continue
[[ "$user" == "Guest" ]] && continue
[[ "$user" == _* ]] && continue
[[ -d "$home" ]] || continue
[[ "$home" == /Users/* ]] || continue
[[ "$shell" == */zsh || "$shell" == */bash ]] || continue
target_zshrc="$home/.zshrc"
ff_dir="$home/.config/fastfetch"
target_fastfetch="$ff_dir/config.jsonc"
group="$(id -gn "$user" 2>/dev/null || echo staff)"
if [[ -f "$target_zshrc" ]] && cmp -s "$tmp_zshrc" "$target_zshrc"; then
echo "[SKIP] $user - .zshrc sudah sesuai template"
else
if [[ -f "$target_zshrc" && ! -f "$home/.zshrc.original" ]]; then
sudo cp -p "$target_zshrc" "$home/.zshrc.original"
sudo chown "$user:$group" "$home/.zshrc.original"
echo "[BACKUP] $user - .zshrc lama -> .zshrc.original"
fi
sudo cp "$tmp_zshrc" "$target_zshrc"
sudo chown "$user:$group" "$target_zshrc"
sudo chmod 644 "$target_zshrc"
echo "[APPLY] $user - .zshrc diperbarui"
fi
sudo mkdir -p "$ff_dir"
if [[ ! -f "$target_fastfetch" ]] || ! cmp -s "$tmp_fastfetch" "$target_fastfetch"; then
if [[ -f "$target_fastfetch" && ! -f "$target_fastfetch.original" ]]; then
sudo cp -p "$target_fastfetch" "$target_fastfetch.original"
sudo chown "$user:$group" "$target_fastfetch.original"
echo "[BACKUP] $user - Fastfetch config lama -> config.jsonc.original"
fi
sudo cp "$tmp_fastfetch" "$target_fastfetch"
sudo chown -R "$user:$group" "$home/.config"
sudo chmod 644 "$target_fastfetch"
echo "[APPLY] $user - Fastfetch config diperbarui"
else
echo "[SKIP] $user - Fastfetch config sudah sesuai"
fi
done < <(dscl . -list /Users UniqueID | awk '{print $1":"$2}' | while IFS=: read -r u uid; do
home=$(dscl . -read "/Users/$u" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
shell=$(dscl . -read "/Users/$u" UserShell 2>/dev/null | awk '{print $2}')
printf '%s:x:%s:x:x:%s:%s\n' "$u" "$uid" "$home" "$shell"
done)
echo
echo "Selesai."
echo "Buka terminal baru atau jalankan: exec zsh"
| 1 | #!/usr/bin/env bash |
| 2 | # |
| 3 | # sync-zshrc-all.sh - macOS Tahoe / Apple Silicon |
| 4 | # |
| 5 | # Menyinkronkan: |
| 6 | # 1. template .zshrc |
| 7 | # 2. /usr/local/etc/shell-prompt.zsh |
| 8 | # 3. config Fastfetch per-user |
| 9 | # 4. dependency Homebrew: vivid, fastfetch, coreutils, tree |
| 10 | # |
| 11 | # Jalankan sebagai USER ADMIN biasa, BUKAN dengan "sudo bash ...". |
| 12 | # Script akan meminta sudo hanya ketika diperlukan. |
| 13 | # |
| 14 | # Default: mengambil tiga file dari direktori yang sama dengan script ini. |
| 15 | # Untuk mode remote/Gist, isi URL melalui environment variable: |
| 16 | # ZSHRC_URL=https://... PROMPT_URL=https://... FASTFETCH_CONFIG_URL=https://... ./sync-zshrc-all.sh |
| 17 | |
| 18 | set -euo pipefail |
| 19 | |
| 20 | if [[ "$(uname -s)" != "Darwin" ]]; then |
| 21 | echo "Error: script ini hanya untuk macOS." >&2 |
| 22 | exit 1 |
| 23 | fi |
| 24 | |
| 25 | if [[ "$(id -u)" -eq 0 ]]; then |
| 26 | echo "Jangan jalankan script ini sebagai root." >&2 |
| 27 | echo "Jalankan sebagai user admin biasa: ./sync-zshrc-all.sh" >&2 |
| 28 | exit 1 |
| 29 | fi |
| 30 | |
| 31 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 32 | LOCAL_ZSHRC="$SCRIPT_DIR/zshrc" |
| 33 | LOCAL_PROMPT="$SCRIPT_DIR/shell-prompt.zsh" |
| 34 | LOCAL_FASTFETCH="$SCRIPT_DIR/config.jsonc" |
| 35 | |
| 36 | ZSHRC_URL="${ZSHRC_URL:-}" |
| 37 | PROMPT_URL="${PROMPT_URL:-}" |
| 38 | FASTFETCH_CONFIG_URL="${FASTFETCH_CONFIG_URL:-}" |
| 39 | |
| 40 | GLOBAL_ZSHRC_TEMPLATE="/usr/local/etc/zshrc-template" |
| 41 | PROMPT_FILE="/usr/local/etc/shell-prompt.zsh" |
| 42 | |
| 43 | TMP_DIR="$(mktemp -d)" |
| 44 | trap 'rm -rf "$TMP_DIR"' EXIT |
| 45 | |
| 46 | need_cmd() { |
| 47 | command -v "$1" >/dev/null 2>&1 |
| 48 | } |
| 49 | |
| 50 | fetch_or_local() { |
| 51 | # fetch_or_local URL LOCAL_FILE DEST_TMP |
| 52 | local url="$1" local_file="$2" dest="$3" |
| 53 | if [[ -n "$url" ]]; then |
| 54 | if ! curl -fsSL "$url" -o "$dest"; then |
| 55 | echo "Error: gagal download $url" >&2 |
| 56 | exit 1 |
| 57 | fi |
| 58 | else |
| 59 | if [[ ! -f "$local_file" ]]; then |
| 60 | echo "Error: file lokal tidak ditemukan: $local_file" >&2 |
| 61 | exit 1 |
| 62 | fi |
| 63 | cp "$local_file" "$dest" |
| 64 | fi |
| 65 | } |
| 66 | |
| 67 | sync_root_file() { |
| 68 | # sync_root_file SOURCE DEST LABEL MODE |
| 69 | local src="$1" dest="$2" label="$3" mode="$4" |
| 70 | if [[ ! -f "$dest" ]] || ! cmp -s "$src" "$dest"; then |
| 71 | sudo mkdir -p "$(dirname "$dest")" |
| 72 | sudo cp "$src" "$dest" |
| 73 | sudo chown root:wheel "$dest" |
| 74 | sudo chmod "$mode" "$dest" |
| 75 | echo " -> $label diperbarui." |
| 76 | else |
| 77 | echo " -> $label sudah sesuai, tidak ada perubahan." |
| 78 | fi |
| 79 | } |
| 80 | |
| 81 | echo "== 0. Pastikan Homebrew tersedia ==" |
| 82 | if ! need_cmd brew; then |
| 83 | echo "Error: Homebrew belum terinstall." >&2 |
| 84 | echo "Install Homebrew terlebih dahulu dari https://brew.sh" >&2 |
| 85 | exit 1 |
| 86 | fi |
| 87 | |
| 88 | eval "$(brew shellenv)" |
| 89 | |
| 90 | echo |
| 91 | echo "== 1. Pastikan dependency terinstall ==" |
| 92 | need_install=() |
| 93 | need_cmd vivid || need_install+=(vivid) |
| 94 | need_cmd fastfetch || need_install+=(fastfetch) |
| 95 | need_cmd gls || need_install+=(coreutils) |
| 96 | need_cmd tree || need_install+=(tree) |
| 97 | |
| 98 | if (( ${#need_install[@]} > 0 )); then |
| 99 | echo " -> Menginstall: ${need_install[*]}" |
| 100 | brew install "${need_install[@]}" |
| 101 | else |
| 102 | echo " -> vivid, fastfetch, coreutils, tree sudah tersedia." |
| 103 | fi |
| 104 | |
| 105 | echo |
| 106 | echo "== 2. Siapkan source file ==" |
| 107 | tmp_zshrc="$TMP_DIR/zshrc" |
| 108 | tmp_prompt="$TMP_DIR/shell-prompt.zsh" |
| 109 | tmp_fastfetch="$TMP_DIR/config.jsonc" |
| 110 | fetch_or_local "$ZSHRC_URL" "$LOCAL_ZSHRC" "$tmp_zshrc" |
| 111 | fetch_or_local "$PROMPT_URL" "$LOCAL_PROMPT" "$tmp_prompt" |
| 112 | fetch_or_local "$FASTFETCH_CONFIG_URL" "$LOCAL_FASTFETCH" "$tmp_fastfetch" |
| 113 | echo " -> source file siap." |
| 114 | |
| 115 | echo |
| 116 | echo "== 3. Sinkronkan template dan prompt global ==" |
| 117 | sync_root_file "$tmp_zshrc" "$GLOBAL_ZSHRC_TEMPLATE" "$GLOBAL_ZSHRC_TEMPLATE" 644 |
| 118 | sync_root_file "$tmp_prompt" "$PROMPT_FILE" "$PROMPT_FILE" 644 |
| 119 | |
| 120 | echo |
| 121 | echo "== 4. Terapkan .zshrc dan Fastfetch ke user manusia di /Users ==" |
| 122 | while IFS=: read -r user _ uid _ _ home shell; do |
| 123 | # macOS human users umumnya UID >= 501. Skip system/shared/guest users. |
| 124 | (( uid >= 501 )) || continue |
| 125 | [[ "$user" == "Guest" ]] && continue |
| 126 | [[ "$user" == _* ]] && continue |
| 127 | [[ -d "$home" ]] || continue |
| 128 | [[ "$home" == /Users/* ]] || continue |
| 129 | [[ "$shell" == */zsh || "$shell" == */bash ]] || continue |
| 130 | |
| 131 | target_zshrc="$home/.zshrc" |
| 132 | ff_dir="$home/.config/fastfetch" |
| 133 | target_fastfetch="$ff_dir/config.jsonc" |
| 134 | group="$(id -gn "$user" 2>/dev/null || echo staff)" |
| 135 | |
| 136 | if [[ -f "$target_zshrc" ]] && cmp -s "$tmp_zshrc" "$target_zshrc"; then |
| 137 | echo "[SKIP] $user - .zshrc sudah sesuai template" |
| 138 | else |
| 139 | if [[ -f "$target_zshrc" && ! -f "$home/.zshrc.original" ]]; then |
| 140 | sudo cp -p "$target_zshrc" "$home/.zshrc.original" |
| 141 | sudo chown "$user:$group" "$home/.zshrc.original" |
| 142 | echo "[BACKUP] $user - .zshrc lama -> .zshrc.original" |
| 143 | fi |
| 144 | sudo cp "$tmp_zshrc" "$target_zshrc" |
| 145 | sudo chown "$user:$group" "$target_zshrc" |
| 146 | sudo chmod 644 "$target_zshrc" |
| 147 | echo "[APPLY] $user - .zshrc diperbarui" |
| 148 | fi |
| 149 | |
| 150 | sudo mkdir -p "$ff_dir" |
| 151 | if [[ ! -f "$target_fastfetch" ]] || ! cmp -s "$tmp_fastfetch" "$target_fastfetch"; then |
| 152 | if [[ -f "$target_fastfetch" && ! -f "$target_fastfetch.original" ]]; then |
| 153 | sudo cp -p "$target_fastfetch" "$target_fastfetch.original" |
| 154 | sudo chown "$user:$group" "$target_fastfetch.original" |
| 155 | echo "[BACKUP] $user - Fastfetch config lama -> config.jsonc.original" |
| 156 | fi |
| 157 | sudo cp "$tmp_fastfetch" "$target_fastfetch" |
| 158 | sudo chown -R "$user:$group" "$home/.config" |
| 159 | sudo chmod 644 "$target_fastfetch" |
| 160 | echo "[APPLY] $user - Fastfetch config diperbarui" |
| 161 | else |
| 162 | echo "[SKIP] $user - Fastfetch config sudah sesuai" |
| 163 | fi |
| 164 | |
| 165 | done < <(dscl . -list /Users UniqueID | awk '{print $1":"$2}' | while IFS=: read -r u uid; do |
| 166 | home=$(dscl . -read "/Users/$u" NFSHomeDirectory 2>/dev/null | awk '{print $2}') |
| 167 | shell=$(dscl . -read "/Users/$u" UserShell 2>/dev/null | awk '{print $2}') |
| 168 | printf '%s:x:%s:x:x:%s:%s\n' "$u" "$uid" "$home" "$shell" |
| 169 | done) |
| 170 | |
| 171 | echo |
| 172 | echo "Selesai." |
| 173 | echo "Buka terminal baru atau jalankan: exec zsh" |
| 174 |