#!/usr/bin/env bash # # install-synology-prompt.sh # # Universal installer for Synology SysAdmin Prompt. # # ------------------------------------------------------------------------------- # USAGE # ------------------------------------------------------------------------------- # # Recommended: # # bash install-synology-prompt.sh # # Do NOT normally run this installer using: # # sudo bash install-synology-prompt.sh # # The script will request sudo privileges itself when required. # # # What this installer does: # # 1. Verifies that the machine looks like Synology DSM. # 2. Verifies that Bash is available. # 3. Downloads synology-prompt.sh. # 4. Installs it as: # # /etc/synology-prompt.sh # # with: # # owner: root # group: root # mode : 0644 # # 5. Adds a small loader to the current user's ~/.profile. # 6. Preserves existing user configuration. # 7. Adds root integration to /root/.profile. # 8. Preserves Synology's original root profile. # 9. Makes "sudo -i" use Bash + the same prompt. # # # Requirements: # # - Synology DSM # - Bash # - sudo access # - wget or curl # # # Nerd Font: # # Nerd Font is NOT installed on Synology. # Install/use a Nerd Font in your SSH client or terminal. # # ------------------------------------------------------------------------------- set -u # ============================================================================== # CONFIGURATION # ============================================================================== PROMPT_URL="https://gist.darto.id/dartokloning/d0bd9f4e277a4242acbc7fb153c9a440/download/HEAD/synology-prompt.sh" PROMPT_FILE="/etc/synology-prompt.sh" USER_MARKER_BEGIN="# >>> Synology SysAdmin Prompt >>>" USER_MARKER_END="# <<< Synology SysAdmin Prompt <<<" ROOT_MARKER_BEGIN="# >>> Synology SysAdmin Prompt - Root >>>" ROOT_MARKER_END="# <<< Synology SysAdmin Prompt - Root <<<" # ============================================================================== # OUTPUT HELPERS # ============================================================================== info() { printf '\n== %s ==\n' "$1" } ok() { printf ' -> %s\n' "$1" } warn() { printf 'WARNING: %s\n' "$1" >&2 } die() { printf 'ERROR: %s\n' "$1" >&2 exit 1 } # ============================================================================== # DETECT CURRENT USER # ============================================================================== # The installer is intended to be launched as the normal DSM user. if [ "$(id -u)" -eq 0 ]; then die "Jalankan installer sebagai user DSM biasa, bukan dengan 'sudo bash'. Gunakan: bash install-synology-prompt.sh" fi CURRENT_USER="$(id -un)" CURRENT_HOME="${HOME:-}" [ -n "$CURRENT_HOME" ] || die "HOME untuk user ${CURRENT_USER} tidak ditemukan." [ -d "$CURRENT_HOME" ] || die "Home directory tidak ditemukan: ${CURRENT_HOME}" # ============================================================================== # VERIFY SYNOLOGY DSM # ============================================================================== info "1. Memeriksa Synology DSM" if [ ! -f /etc.defaults/VERSION ]; then die "File /etc.defaults/VERSION tidak ditemukan. Mesin ini tidak terlihat seperti Synology DSM." fi DSM_VERSION="$( sed -n 's/^productversion="\([^"]*\)".*/\1/p' \ /etc.defaults/VERSION 2>/dev/null | head -n 1 )" DSM_BUILD="$( sed -n 's/^buildnumber="\([^"]*\)".*/\1/p' \ /etc.defaults/VERSION 2>/dev/null | head -n 1 )" ok "Synology DSM terdeteksi." if [ -n "$DSM_VERSION" ]; then ok "DSM version: ${DSM_VERSION}" fi if [ -n "$DSM_BUILD" ]; then ok "DSM build: ${DSM_BUILD}" fi ok "User: ${CURRENT_USER}" ok "Home: ${CURRENT_HOME}" # ============================================================================== # VERIFY BASH # ============================================================================== info "2. Memeriksa Bash" command -v bash >/dev/null 2>&1 || die "Bash tidak ditemukan." BASH_PATH="$(command -v bash)" ok "Bash ditemukan: ${BASH_PATH}" BASH_VERSION_TEXT="$( bash --version 2>/dev/null | head -n 1 )" [ -n "$BASH_VERSION_TEXT" ] && ok "$BASH_VERSION_TEXT" # ============================================================================== # VERIFY SUDO # ============================================================================== info "3. Memeriksa sudo" command -v sudo >/dev/null 2>&1 || die "sudo tidak ditemukan." printf ' -> Meminta privilege sudo...\n' sudo -v || die "Tidak mendapatkan privilege sudo." ok "sudo siap digunakan." # ============================================================================== # VERIFY DOWNLOAD TOOL # ============================================================================== info "4. Memeriksa downloader" if command -v wget >/dev/null 2>&1; then DOWNLOAD_TOOL="wget" ok "Menggunakan wget." elif command -v curl >/dev/null 2>&1; then DOWNLOAD_TOOL="curl" ok "Menggunakan curl." else die "wget maupun curl tidak ditemukan." fi # ============================================================================== # VERIFY URL # ============================================================================== if [ "$PROMPT_URL" = "PASTE_RAW_GIST_URL_HERE" ] || [ -z "$PROMPT_URL" ]; then die "PROMPT_URL belum diisi. Edit installer dan isi URL raw/download synology-prompt.sh dari Gist." fi # ============================================================================== # TEMPORARY DIRECTORY # ============================================================================== TMP_DIR="$(mktemp -d)" || die "Tidak dapat membuat temporary directory." TMP_PROMPT="${TMP_DIR}/synology-prompt.sh" cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT # ============================================================================== # DOWNLOAD PROMPT # ============================================================================== info "5. Download synology-prompt.sh" if [ "$DOWNLOAD_TOOL" = "wget" ]; then wget -q -O "$TMP_PROMPT" "$PROMPT_URL" || die "Gagal download: ${PROMPT_URL}" else curl -fsSL "$PROMPT_URL" -o "$TMP_PROMPT" || die "Gagal download: ${PROMPT_URL}" fi [ -s "$TMP_PROMPT" ] || die "File hasil download kosong." # Basic sanity check. if ! grep -q 'Synology DSM SysAdmin Prompt\|Universal Powerline-style SysAdmin prompt' "$TMP_PROMPT"; then warn "File berhasil didownload tetapi signature prompt tidak ditemukan." warn "Periksa PROMPT_URL sebelum melanjutkan." exit 1 fi ok "Prompt berhasil didownload." # ============================================================================== # INSTALL SYSTEM-WIDE PROMPT # ============================================================================== info "6. Install system-wide prompt" sudo cp "$TMP_PROMPT" "$PROMPT_FILE" || die "Gagal menyalin prompt ke ${PROMPT_FILE}." sudo chown root:root "$PROMPT_FILE" || die "Gagal mengatur ownership ${PROMPT_FILE}." sudo chmod 0644 "$PROMPT_FILE" || die "Gagal mengatur permission ${PROMPT_FILE}." ok "Installed: ${PROMPT_FILE}" ok "Owner: root:root" ok "Mode: 0644" # ============================================================================== # USER PROFILE # ============================================================================== info "7. Konfigurasi user ${CURRENT_USER}" USER_PROFILE="${CURRENT_HOME}/.profile" # Create profile if it does not exist. if [ ! -e "$USER_PROFILE" ]; then touch "$USER_PROFILE" || die "Tidak dapat membuat ${USER_PROFILE}." ok "Membuat ${USER_PROFILE}." fi # Backup only once. USER_BACKUP="${USER_PROFILE}.before-synology-prompt" if [ ! -e "$USER_BACKUP" ]; then cp -a "$USER_PROFILE" "$USER_BACKUP" || die "Gagal membuat backup ${USER_BACKUP}." ok "Backup dibuat: ${USER_BACKUP}" else ok "Backup user profile sudah ada, tidak ditimpa." fi # Remove an existing managed block, making installation idempotent. USER_TMP="${TMP_DIR}/user-profile" awk \ -v begin="$USER_MARKER_BEGIN" \ -v end="$USER_MARKER_END" ' $0 == begin { skip=1; next } $0 == end { skip=0; next } !skip { print } ' "$USER_PROFILE" > "$USER_TMP" || die "Gagal memproses ${USER_PROFILE}." cat >> "$USER_TMP" <<'EOF' # >>> Synology SysAdmin Prompt >>> # # Start Bash for interactive sessions and load the system-wide prompt. # case "$-" in *i*) if [ -z "${SYNO_USER_PROMPT:-}" ]; then export SYNO_USER_PROMPT=1 exec bash --noprofile --rcfile /etc/synology-prompt.sh -i fi ;; esac # <<< Synology SysAdmin Prompt <<< EOF cp "$USER_TMP" "$USER_PROFILE" || die "Gagal memperbarui ${USER_PROFILE}." ok "User profile dikonfigurasi." # ============================================================================== # ROOT PROFILE # ============================================================================== info "8. Konfigurasi root" ROOT_PROFILE="/root/.profile" ROOT_BACKUP="/root/.profile.before-synology-prompt" # DSM normally has /root/.profile, but create it safely if absent. if ! sudo test -e "$ROOT_PROFILE"; then sudo touch "$ROOT_PROFILE" || die "Gagal membuat ${ROOT_PROFILE}." sudo chown root:root "$ROOT_PROFILE" sudo chmod 0600 "$ROOT_PROFILE" ok "Membuat ${ROOT_PROFILE}." fi # Backup only once. if ! sudo test -e "$ROOT_BACKUP"; then sudo cp -a "$ROOT_PROFILE" "$ROOT_BACKUP" || die "Gagal membuat backup ${ROOT_BACKUP}." ok "Backup dibuat: ${ROOT_BACKUP}" else ok "Backup root profile sudah ada, tidak ditimpa." fi ROOT_TMP="${TMP_DIR}/root-profile" sudo cat "$ROOT_PROFILE" | awk \ -v begin="$ROOT_MARKER_BEGIN" \ -v end="$ROOT_MARKER_END" ' $0 == begin { skip=1; next } $0 == end { skip=0; next } !skip { print } ' > "$ROOT_TMP" || die "Gagal memproses ${ROOT_PROFILE}." cat >> "$ROOT_TMP" <<'EOF' # >>> Synology SysAdmin Prompt - Root >>> # # Preserve Synology's original root initialization above. # For interactive root login (for example: sudo -i), # replace ash with Bash and load the system-wide prompt. # case "$-" in *i*) if [ -z "${SYNO_ROOT_PROMPT:-}" ]; then export SYNO_ROOT_PROMPT=1 cd /root 2>/dev/null || true exec bash --noprofile --rcfile /etc/synology-prompt.sh -i fi ;; esac # <<< Synology SysAdmin Prompt - Root <<< EOF sudo cp "$ROOT_TMP" "$ROOT_PROFILE" || die "Gagal memperbarui ${ROOT_PROFILE}." sudo chown root:root "$ROOT_PROFILE" ok "Root profile dikonfigurasi." # ============================================================================== # VERIFY # ============================================================================== info "9. Verifikasi" if sudo test -r "$PROMPT_FILE"; then ok "${PROMPT_FILE} readable." else die "${PROMPT_FILE} tidak dapat dibaca." fi if grep -Fq "$USER_MARKER_BEGIN" "$USER_PROFILE"; then ok "User loader ditemukan." else die "User loader tidak ditemukan." fi if sudo grep -Fq "$ROOT_MARKER_BEGIN" "$ROOT_PROFILE"; then ok "Root loader ditemukan." else die "Root loader tidak ditemukan." fi # ============================================================================== # DONE # ============================================================================== printf '\n' printf '====================================================================\n' printf ' Synology SysAdmin Prompt berhasil di-install\n' printf '====================================================================\n' printf '\n' printf 'Prompt file:\n' printf ' %s\n' "$PROMPT_FILE" printf '\nUser:\n' printf ' %s\n' "$CURRENT_USER" printf '\nCara menggunakan:\n' printf '\n' printf ' 1. Logout dari SSH lalu login kembali.\n' printf '\n' printf ' ATAU untuk test tanpa logout:\n' printf '\n' printf ' exec bash --noprofile --rcfile %s -i\n' "$PROMPT_FILE" printf '\n' printf ' 2. Untuk masuk ke root:\n' printf '\n' printf ' sudo -i\n' printf '\n' printf ' Root otomatis menggunakan warning palette merah/kuning.\n' printf '\n' printf ' 3. Jika icon Powerline/Nerd Font tidak tampil dengan benar,\n' printf ' gunakan Nerd Font pada terminal CLIENT, bukan pada Synology.\n' printf '\n' printf 'Contoh prompt user:\n' printf '\n' printf ' ╭  user   NAS   ~   52%%   Selasa, 29 September 2026   14:00:00 \n' printf ' ╰> $\n' printf '\n' printf 'Contoh root:\n' printf '\n' printf ' sudo -i\n' printf '\n' printf ' ╭  root   NAS   ~   24%%  ...\n' printf ' ╰> #\n' printf '\n' printf 'Backup:\n' printf ' User : %s\n' "$USER_BACKUP" printf ' Root : %s\n' "$ROOT_BACKUP" printf '\n' printf 'Selesai.\n'