JustToThePoint English Website Version
JustToThePoint en español

Arch Linux Post-Installation: Extras, Noctalia, and Backup Strategy

If you find yourself in a hole, stop digging, Will Rogers

image info

Introduction

Welcome to the final chapter of the Arch Linux post-installation series. In this guide, we are going to polish the system with a suite of essential extra tools: the lightning-fast terminal file manager yazi, the Wayland-native wallpaper daemon swww, fun and useful utilities like bash-insulter and LocalSend. We then dive deep into customizing the Noctalia environment, setting up avatars, dynamic wallpapers, and location-based weather. Finally, to ensure your hard work is safe, we conclude by establishing a robust three-tier backup strategy using Clonezilla for disk imaging, rsync for dotfile synchronization, and Timeshift for system-level snapshots.

Install and configure extra tools and Noctalia

#!/usr/bin/env bash
# ── 17-extras.sh ──────────────────────────────────────────────────────────────
# Install and configure extra tools:
#   1. yazi        — terminal file manager with image previews
#   2. swww        — Wayland wallpaper daemon with transitions
#   3. bash-insulter — insults you on wrong commands
#   4. fortunes    — install fortune-mod, link your custom collection
#   5.  LocalSend     — LAN file transfer
#   6.  GIMP          — image editor
#   7.  Ristretto     — fast image viewer
#   8.  Noctalia      — configuration (avatar, wallpaper, weather)
#
# Run: bash 17-extras.sh
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail

DOTFILES="$HOME/dotfiles"
MYARCH="$DOTFILES/myArch"

# ── 1. yazi — terminal file manager ──────────────────────────────────────────
# yazi is written in Rust. Supports image preview via kitty protocol (best
# on Wayland), sixel, and chafa fallback.
# Integrates with: fd, ripgrep, fzf, bat, zoxide, imagemagick.

echo "── Installing yazi..."
paru -S --needed --noconfirm \
  yazi \
  ffmpegthumbnailer \
  jq \
  poppler \
  fd \
  ripgrep \
  fzf \
  zoxide \
  imagemagick

echo "  ✅  yazi $(yazi --version 2>/dev/null | head -1)"

# yazi config directory — create it so yazi doesn't complain on first run
mkdir -p "$HOME/.config/yazi"

# yazi theme — link from dotfiles if it exists, otherwise create a minimal one
if [[ -f "$MYARCH/config/yazi/theme.toml" ]]; then
  ln -sf "$MYARCH/config/yazi/theme.toml" "$HOME/.config/yazi/theme.toml"
  echo "  🔗  yazi theme linked"
fi

# ── 2. swww — Wayland wallpaper daemon with animated transitions ──────────────
echo "── Installing swww..."
paru -S --needed --noconfirm swww
echo "  ✅  swww $(swww --version 2>/dev/null)"

# ── 3. bash-insulter ─────────────────────────────────────────────────────────
# bash-insulter prints a random insult when you type an invalid command.
# Source: https://github.com/hkbakke/bash-insulter
# Installed to /etc/bash.command-not-found, sourced from .zshrc.
INSULTER="/etc/bash.command-not-found"
DOTFILES_INSULTER="$MYARCH/config/zsh/bash.command-not-found"

if [[ -f "$DOTFILES_INSULTER" ]]; then
  echo "── Installing bash-insulter from dotfiles..."
  sudo cp "$DOTFILES_INSULTER" "$INSULTER"
  sudo chmod 644 "$INSULTER"
  echo "  ✅  $INSULTER installed from dotfiles"
elif [[ ! -f "$INSULTER" ]]; then
  echo "── Cloning bash-insulter from GitHub..."
  TMPDIR=$(mktemp -d)
  git clone --depth 1 https://github.com/hkbakke/bash-insulter.git "$TMPDIR/bash-insulter"
  sudo cp "$TMPDIR/bash-insulter/src/bash.command-not-found" "$INSULTER"
  sudo chmod 644 "$INSULTER"
  # Also save to dotfiles for future use
  mkdir -p "$(dirname "$DOTFILES_INSULTER")"
  cp "$INSULTER" "$DOTFILES_INSULTER"
  rm -rf "$TMPDIR"
  echo "  ✅  bash-insulter installed and saved to dotfiles"
else
  echo "  ✅  bash-insulter already at $INSULTER"
fi

# ── 4. fortune-mod — required to read fortune files ──────────────────────────
# fortune-mod provides the `fortune` binary that reads from .dat index files.
# strfile creates the .dat binary index from a text fortune file.
# Format: quotes separated by a line containing only %%
echo "── Installing fortune-mod..."
sudo pacman -S --needed --noconfirm fortune-mod

FORTUNE_SRC="$MYARCH/config/zsh/fortune"
FORTUNE_DST="$HOME/dotfiles/myArch/config/zsh/fortune"

if [[ -f "$FORTUNE_SRC" ]]; then
  # Build the binary index (.dat file) required by fortune
  # strfile reads the text file and creates fortune.dat alongside it
  strfile "$FORTUNE_SRC" "${FORTUNE_SRC}.dat" 2>/dev/null || true
  echo "  ✅  Fortune index built"
  echo "  ✅  fortune count: $(grep -c '%%' "$FORTUNE_SRC" 2>/dev/null || echo '?') quotes"
fi

# ── 5. LocalSend ─────────────────────────────────────────────────────────────
# LAN file transfer. It is cross-platform (Windows/macOS/Android/Linux).
echo "── Installing LocalSend..."
paru -S --needed --noconfirm localsend-bin
echo "  ✅  LocalSend installed"

# ── 6. GIMP ───────────────────────────────────────────────────────────────────
echo "── Installing GIMP..."
sudo pacman -S --needed --noconfirm gimp
echo "  ✅  GIMP $(gimp --version 2>/dev/null | head -1)"

# ── 7. Ristretto ─────────────────────────────────────────────────────────────
# Lightweight Xfce image viewer.
echo "── Installing Ristretto..."
sudo pacman -S --needed --noconfirm ristretto
echo "  ✅  Ristretto installed"

# ══════════════════════════════════════════════════════════════════════════════
# 10. NOCTALIA CONFIGURATION
# ══════════════════════════════════════════════════════════════════════════════
#
# Noctalia reads ~/.config/noctalia/settings.json on startup and watches it
# with a FileView — changes are picked up within ~500ms without restarting.
#
# We use `jq` (installed in step 1) to merge our keys into whatever Noctalia
# already wrote, preserving all other values (* = object merge in jq).
echo "── Configuring Noctalia..."

# ── Profile picture ───────────────────────────────────────────────────────────
# ~/.face      — read by greetd/tuigreet for the login screen avatar
# ~/.face.icon — fallback for SDDM and AccountsService
# Noctalia general.avatarImage — shown on lock screen + profile card
AVATAR_SRC="$HOME/dotfiles/docs/misImagenes/maximoAnawim.jpeg"

if [[ -f "$AVATAR_SRC" ]]; then
  # Copy (not symlink) — some login managers reject symlinks for security
  cp "$AVATAR_SRC" "$HOME/.face"
  cp "$AVATAR_SRC" "$HOME/.face.icon"
  echo "  ✅  ~/.face and ~/.face.icon → $AVATAR_SRC"
else
  echo "  ⚠️  Avatar not found: $AVATAR_SRC"
  echo "      Place your photo there and re-run, or set it in Noctalia Settings GUI"
  AVATAR_SRC=""   # leave avatarImage empty so Noctalia uses its default
fi

# ── settings.json ─────────────────────────────────────────────────────────────
NOCTALIA_CFG="$HOME/.config/noctalia/settings.json"
mkdir -p "$HOME/.config/noctalia"

# If Noctalia has never run, settings.json does not exist yet.
# Create an empty object so jq has something to merge into.
# Noctalia will add its own defaults on first launch and merge with what we want to change.
if [[ ! -f "$NOCTALIA_CFG" ]]; then
  echo '{}' > "$NOCTALIA_CFG"
  echo "  ℹ️   Created empty settings.json — Noctalia will populate defaults on first run"
fi

# jq merge strategy:
#   (.section // {}) ensures we don't fail if a section is missing entirely.
#   * merges objects: right-hand keys overwrite, others are preserved.
#   --arg passes shell strings; numbers are embedded directly in the filter.
jq \
  --arg avatar  "$AVATAR_SRC" \
  --arg walldir "$HOME/wallpaper" \
  '
  .general = (.general // {}) * {
    "avatarImage":            $avatar,
    "language":               "en",
    "telemetryEnabled":       false,
    "showChangelogOnStartup": false
  } |

  .wallpaper = (.wallpaper // {}) * {
    "directory":          $walldir,
    "enabled":            true,
    "randomEnabled":      true,
    "randomIntervalSec":  600,
    "transitionDuration": 1200,
    "fillMode":           "crop",
    "monitorDirectories": [
      {
        "directory": "/home/nmaximo7/wallpaper",
        "name": "HDMI-A-1",
        "wallpaper": ""
      }
    ]
  } |

  # Noctalia weather uses open-meteo.com — no API key required.
  # lat/lon are numbers (not strings) — jq embeds them without quotes.
  .weather = (.weather // {}) * {
    "city":      "Málaga",
    "latitude":  36.72,
    "longitude": -4.42,
    "useMetric": true
  }
  ' \
  "$NOCTALIA_CFG" > "${NOCTALIA_CFG}.tmp" \
  && mv "${NOCTALIA_CFG}.tmp" "$NOCTALIA_CFG"

echo "  ✅  $NOCTALIA_CFG updated"


echo
echo "✅  17-extras: done"
echo
echo "── Summary of what was installed:"
echo "   yazi      — terminal file manager  (y to open, q to quit)"
echo "   swww      — wallpaper daemon  (Mod+W = random wallpaper)"
echo "   insulter  — /etc/bash.command-not-found"
echo "   fortune   — $(command -v fortune 2>/dev/null || echo 'not found')"
echo "   GIMP      — image editor"
echo "   Ristretto — image viewer"
echo "   Noctalia  — configuration updated"
echo

Backup strategy

  1. Full Disk Imaging. Clonezilla. Use Clonezilla for complete system recovery (bare-metal restore exactly as it was).
    Every 3 - 4 months.
    Default settings, device-image (we want to create an image instead of cloning disk-to-disk); storage: local_dev (we want to save the image locally to an external drive, e.g., /dev/sdb1, archclone directory for reference); operation: savedisk, save local disk as an image (save an image of the whole local drive, e.g., /dev/sdc, TS256GMTS800, 238,47 SSD). Options: Skip checking/repairing source file system (faster, safe if system is healthy) and Yes, check the saved image.
  2. Incremental Backups (dotfiles & personal data):
    Run this daily.
    rsync \
    --archive \  # Preserve structure, symlinks, timestamps
    --verbose \  # Show progress
    --human-readable \  # Readable output
    --delete \  # Mirror destination (remove deleted files)
    --no-perms \  # Avoid permission issues across systems
    --no-group \  # Avoid group mismatches
    --omit-dir-times \  # Prevent unnecessary timestamp updates
    --exclude='.git/' \
    --exclude='*.pyc' \
    --exclude='__pycache__/' \
    --exclude='*.tmp' \
    "$DOTFILES_SRC/" \
    "$DOTFILES_DST/"
    
  3. System Snapshots. Timeshift allows to create incremental snapshots of the file system at regular intervals, which can then be restored at a later date to undo all changes to the system.
    Timeshift provides quick rollback (perfect after system updates or experiments). Install: sudo pacman timeshift.
    Snapshot Type (RSYNC), Select Snapshot Location (external drive, e.g, sdb1), Snapshot Levels (e.g, Daily keep 3; Monthly keep 1), User Home Directories (Include All Files - full restore capability).
    This offers fast recovery fron broken updates and misconfigurations.
  4. Critical Improvements:
    Never rely on a single backup location. At least 2 copies (e.g., external + network).
    Test your backups. A backup you never restored is not a secure backup.
    Automate rsync with cron.
Bitcoin donation

JustToThePoint Copyright © 2011 - 2026 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.