shell-automation
Use when the user asks about Unraid shell scripting, User Scripts plugin, event hooks, boot scripts, CLI tools, cron jobs, or system automation. Examples: "user scripts", "unraid script", "emhttp_event", "unraid boot config", "/boot/config/go", "unraid cron".
From unraid-assistantnpx claudepluginhub jamesprial/prial-plugins --plugin unraid-assistantThis skill uses the workspace's default tool permissions.
Shell Automation on Unraid
Persistence Model
Unraid runs entirely from RAM. All persistent scripts and configuration must reside on the USB flash drive under /boot/config/. Files outside this path are lost on reboot.
Master Boot Script
/boot/config/go executes during boot before the WebGUI starts. Use it to install SSH keys, event hooks, kernel modules, and network tuning:
#!/bin/bash
# /boot/config/go — runs at boot before WebGUI
# Restore SSH authorized keys
mkdir -p /root/.ssh
cp /boot/config/ssh/authorized_keys /root/.ssh/authorized_keys
chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys
# Install custom event hook
cp /boot/config/custom/my-hook.sh \
/usr/local/emhttp/plugins/user.scripts/event/array_started/
# Network tuning
echo 1 > /proc/sys/net/ipv4/ip_forward
# Start background services
/boot/config/custom/my-daemon.sh &
User Scripts Plugin
The CA User Scripts plugin provides a WebGUI for managing persistent bash scripts.
Storage Location
/boot/config/plugins/user.scripts/scripts/<script_name>/script
Each script lives in its own directory. The executable file must be named script.
Scheduling Options
| Schedule | When |
|---|---|
| At Array Start | When array comes online |
| At Array Stop | When array goes offline |
| Custom Cron | Any cron expression |
| At First Array Start Only | Once after boot, on first array start |
| Manual Only | Run from WebGUI or CLI |
Create a User Script
mkdir -p /boot/config/plugins/user.scripts/scripts/my-backup
cat > /boot/config/plugins/user.scripts/scripts/my-backup/script << 'SCRIPT'
#!/bin/bash
#name=Nightly Backup
#description=Backs up appdata to array
rsync -a /mnt/user/appdata/ /mnt/user/backups/appdata/
/usr/local/emhttp/webGui/scripts/notify \
-e "Backup" -s "Nightly backup completed" -i "normal"
SCRIPT
chmod +x /boot/config/plugins/user.scripts/scripts/my-backup/script
Scripts run as root with full system access.
Event System (emhttp_event)
The emhttp_event dispatcher runs scripts placed in event directories when system events fire.
Script Location
/usr/local/emhttp/plugins/<plugin_name>/event/<EVENT_NAME>/
Startup Event Sequence
Events fire in this order during boot:
| Order | Event | Meaning |
|---|---|---|
| 1 | driver_loaded | Kernel drivers ready |
| 2 | starting | emhttp initializing |
| 3 | array_started | Array disks online |
| 4 | disks_mounted | Filesystems mounted |
| 5 | docker_started | Docker daemon running |
| 6 | libvirt_started | libvirt/KVM ready |
| 7 | started | System fully operational |
Shutdown Event Sequence
Reverse order: stopping -> libvirt_stopped -> docker_stopped -> disks_unmounted -> array_stopped -> stopped -> driver_unloaded
Event Script Rules
- Scripts must be executable (
chmod +x) - IMPORTANT: Long-running scripts must background (
&) to avoid blocking emhttp - Scripts run as root
- Event directories under
/usr/local/emhttp/are in RAM and must be recreated on each boot (use/boot/config/go)
Example Event Hook
# /boot/config/custom/on-array-start.sh
# Install from go: cp /boot/config/custom/on-array-start.sh \
# /usr/local/emhttp/plugins/user.scripts/event/array_started/
#!/bin/bash
# Start a service after array is online
docker start myservice &
/usr/local/emhttp/webGui/scripts/notify \
-e "Array" -s "Array started, services launched" -i "normal" &
CLI Tools
mdcmd -- Array Management
| Command | Purpose |
|---|---|
mdcmd check NOCORRECT | Start non-correcting parity check |
mdcmd check CORRECT | Start correcting parity check |
mdcmd nocheck | Cancel running parity check |
mdcmd spinup N | Spin up disk N |
mdcmd spindown N | Spin down disk N |
mdcmd set md_write_method 1 | Set write method (1=reconstruct) |
mdcmd status | Array status |
emcmd -- Array Start/Stop
| Command | Purpose |
|---|---|
emcmd cmdStart=Start | Start the array |
emcmd cmdStop=Stop | Stop the array |
notify -- System Notifications
/usr/local/emhttp/webGui/scripts/notify \
-e "Event Title" \
-s "Subject line" \
-d "Detailed description" \
-i "normal" # normal, warning, alert
The -i flag sets importance level, which determines notification routing (email, push, etc.) based on Unraid notification settings.
mover -- Cache-to-Array Migration
Run /usr/local/sbin/mover start to trigger manually, or /usr/local/sbin/mover start -f to force (ignore age threshold).
Cron Scheduling
User Scripts creates cron entries automatically. For manual cron, add to /boot/config/go:
echo "0 3 * * * /boot/config/custom/nightly-job.sh" >> /var/spool/cron/crontabs/root
Notification Integrations
Combine the built-in notify with external webhooks in User Scripts:
#!/bin/bash
MSG="Parity check finished at $(date)"
# Unraid native notification
/usr/local/emhttp/webGui/scripts/notify -e "Parity" -s "$MSG" -i "normal"
# ntfy.sh push
curl -s -d "$MSG" https://ntfy.sh/my-unraid-alerts
# Discord webhook
curl -s -H "Content-Type: application/json" \
-d "{\"content\": \"$MSG\"}" https://discord.com/api/webhooks/YOUR_URL
Key Configuration Files
| Path | Purpose |
|---|---|
/boot/config/go | Master startup script (runs before WebGUI) |
/boot/config/domain.cfg | VM manager settings |
/boot/config/docker.cfg | Docker daemon settings |
/boot/config/shares/<Name>.cfg | Per-share config (key=value pairs) |
/boot/config/vfio-pci.cfg | VFIO passthrough device bindings |
/boot/syslinux/syslinux.cfg | Kernel boot parameters (IOMMU, etc.) |
/boot/config/plugins/user.scripts/scripts/ | User Scripts storage |
Debugging
Test a user script manually with bash /boot/config/plugins/user.scripts/scripts/my-script/script. Watch emhttp events with tail -f /var/log/syslog | grep emhttp. Check recent syslog entries with tail -100 /var/log/syslog.