Última actividad 1793000767

Nerd Fonts patches developer targeted fonts with a high number of glyphs (icons). Specifically to add a high number of extra glyphs from popular ‘iconic fonts’ such as Font Awesome, Devicons, Octicons, and others.

Revisión 76c3ad463348ef00a3287d77f51f07d2b40d16e3

install-nerd-fonts.sh Sin formato
1#!/usr/bin/env bash
2set -Eeuo pipefail
3
4DEST='/usr/local/share/fonts/nerd-fonts'
5API='https://api.github.com/repos/ryanoasis/nerd-fonts/releases/latest'
6
7if [[ ! -t 0 ]]; then echo 'Jalankan secara interaktif di terminal.' >&2; exit 1; fi
8if [[ $EUID -eq 0 ]]; then echo 'Jalankan sebagai user biasa (tanpa sudo); script akan meminta sudo saat perlu.' >&2; exit 1; fi
9for cmd in curl python3 tar find mktemp sudo fc-cache; do
10 if ! command -v "$cmd" >/dev/null 2>&1; then
11 echo "Dependency belum tersedia: $cmd" >&2
12 echo 'Install dahulu: sudo apt update && sudo apt install curl python3 xz-utils fontconfig sudo ca-certificates' >&2
13 exit 1
14 fi
15done
16if ! tar --help 2>/dev/null | grep -q -- '--xz'; then
17 echo 'tar tidak mendukung xz. Install: sudo apt install xz-utils' >&2; exit 1
18fi
19WORK=$(mktemp -d)
20trap 'rm -rf "$WORK"' EXIT
21printf 'Mengambil katalog rilis Nerd Fonts resmi...\n'
22if ! curl -fLsS --retry 3 --connect-timeout 15 --max-time 90 \
23 -H 'Accept: application/vnd.github+json' -H 'User-Agent: Debian-Nerd-Fonts-Installer' \
24 "$API" -o "$WORK/release.json"; then
25 echo 'Gagal mengambil data GitHub API (periksa internet atau rate limit).' >&2; exit 1
26fi
27if ! python3 - "$WORK/release.json" "$WORK/catalog.tsv" "$WORK/version" <<'PY'
28import json,sys
29with open(sys.argv[1],encoding='utf-8') as f: data=json.load(f)
30assets=[]
31for a in data.get('assets',[]):
32 name=a.get('name','')
33 if name.endswith('.tar.xz') and not name.endswith('xv.tar.xz'):
34 url=a.get('browser_download_url','')
35 if url.startswith('https://github.com/ryanoasis/nerd-fonts/releases/download/'):
36 assets.append((name[:-7],url,a.get('digest') or ''))
37assets.sort(key=lambda x:x[0].lower())
38if not assets: raise SystemExit('Tidak ada arsip font .tar.xz pada rilis.')
39with open(sys.argv[2],'w',encoding='utf-8') as f:
40 for name,url,digest in assets: f.write(f'{name}\t{url}\t{digest}\n')
41with open(sys.argv[3],'w') as f:f.write(data.get('tag_name','unknown'))
42PY
43then echo 'Katalog rilis tidak valid.' >&2; exit 1; fi
44mapfile -t LINES < "$WORK/catalog.tsv"
45VERSION=$(cat "$WORK/version")
46printf '\nNerd Fonts %s | Tujuan: %s\n\n' "$VERSION" "$DEST"
47for i in "${!LINES[@]}"; do
48 IFS=$'\t' read -r name url digest <<< "${LINES[$i]}"
49 status=''
50 [[ -d "$DEST/$name" ]] && status=' [TERPASANG]'
51 printf '%3d. %-28s%s\n' "$((i+1))" "$name" "$status"
52done
53printf '\nMasukkan nomor, contoh 1,2,4 (atau all untuk semua; q untuk keluar): '
54read -r selection
55[[ $selection == q || $selection == Q ]] && exit 0
56indices=()
57if [[ $selection == all || $selection == ALL ]]; then
58 for i in "${!LINES[@]}"; do indices+=("$i"); done
59else
60 selection=${selection//[[:space:]]/}
61 if [[ ! $selection =~ ^[0-9]+(,[0-9]+)*$ ]]; then echo 'Format pilihan tidak valid.' >&2; exit 1; fi
62 declare -A seen=()
63 IFS=',' read -ra choices <<< "$selection"
64 for n in "${choices[@]}"; do
65 n=$((10#$n))
66 if (( n < 1 || n > ${#LINES[@]} )); then echo "Nomor tidak tersedia: $n" >&2; exit 1; fi
67 if [[ ! ${seen[$n]+x} ]]; then indices+=("$((n-1))"); seen[$n]=1; fi
68 done
69fi
70printf '\nAkan memasang %d keluarga font secara GLOBAL. Lanjutkan? [y/N]: ' "${#indices[@]}"
71read -r confirm
72[[ $confirm == y || $confirm == Y ]] || exit 0
73sudo -v
74sudo install -d -m 755 "$DEST"
75installed=0; failed=0
76for idx in "${indices[@]}"; do
77 IFS=$'\t' read -r name url digest <<< "${LINES[$idx]}"
78 printf '\n==> %s\n' "$name"
79 archive="$WORK/$name.tar.xz"
80 stage="$WORK/stage-$idx"
81 mkdir -p "$stage"
82 if ! curl -fL --retry 3 --connect-timeout 15 "$url" -o "$archive"; then
83 echo "GAGAL download: $name" >&2; ((failed+=1)); continue
84 fi
85 if [[ $digest == sha256:* ]]; then
86 if ! printf '%s %s\n' "${digest#sha256:}" "$archive" | sha256sum -c --status; then
87 echo "GAGAL checksum SHA256: $name" >&2; ((failed+=1)); continue
88 fi
89 fi
90 if ! tar -tJf "$archive" >/dev/null 2>&1 || ! tar -xJf "$archive" -C "$stage" --no-same-owner --no-same-permissions; then
91 echo "GAGAL ekstraksi: $name" >&2; ((failed+=1)); continue
92 fi
93 mapfile -d '' fontfiles < <(find "$stage" -type f \( -iname '*.ttf' -o -iname '*.otf' \) -print0)
94 if (( ${#fontfiles[@]} == 0 )); then echo "Tidak ada file font: $name" >&2; ((failed+=1)); continue; fi
95 target="$DEST/$name"
96 # Staging pada filesystem tujuan, lalu ganti direktori font setelah semua file disalin.
97 tmp_target="$DEST/.${name}.new.$$"
98 sudo install -d -m 755 "$tmp_target"
99 ok=1
100 for font in "${fontfiles[@]}"; do
101 if ! sudo install -m 644 "$font" "$tmp_target/$(basename "$font")"; then ok=0; break; fi
102 done
103 if (( ok == 0 )); then sudo rm -rf -- "$tmp_target"; echo "GAGAL copy: $name" >&2; ((failed+=1)); continue; fi
104 if ! sudo rm -rf -- "$target" || ! sudo mv -- "$tmp_target" "$target"; then
105 echo "GAGAL finalisasi: $name" >&2; ((failed+=1)); continue
106 fi
107 printf 'OK: %s (%d file font)\n' "$name" "${#fontfiles[@]}"
108 ((installed+=1))
109done
110printf '\nMemperbarui font cache...\n'
111sudo fc-cache -f "$DEST"
112printf '\nSelesai. Berhasil: %d | Gagal: %d\n' "$installed" "$failed"
113printf 'Verifikasi: fc-list | grep -i "Nerd Font"\n'
114(( failed == 0 ))
115