Bash Scripts I Reuse on Every New Server
Advertisement
Every server I take over—whether it is a fresh VPS or a box a client has been running for years—gets the same small set of scripts dropped into /usr/local/bin.
None of them are clever. They are the kind of thing you'd write in five minutes and forget about. Yet, I've been carrying these exact scripts, lightly updated, for years. They just keep paying for themselves.
1. The "what does this server look like" snapshot
The very first thing I run on any server, new or unfamiliar, is a quick snapshot script. It prints disk usage, memory, load average, the top processes by memory, and anything listening on a network port:
#!/bin/bash
# server-snapshot.sh
echo "== Uptime & Load =="
uptime
echo -e "\n== Disk Usage =="
df -hT --total | grep -E '^(Total|/dev)'
echo -e "\n== Memory =="
free -h
echo -e "\n== Top 5 Memory Consumers =="
ps aux --sort=-%mem | head -6
echo -e "\n== Listening Ports =="
ss -tulpn | grep LISTEN
It is nothing you couldn't type manually. But typing five separate commands every time you log into a server you don't fully remember is exactly how things get missed. One script, one glance, and I have a mental model of the box before I touch a single config file.
2. Finding what's actually eating the disk
"Disk is full" is one of the most common alerts I get. The cause is almost never where people expect it to be. This script walks down from root, sorts directories by size, and stops at a sane depth so it doesn't bury you in thousands of lines of output:
#!/bin/bash
# disk-hogs.sh
du -ahx --max-depth="${1:-3}" / 2>/dev/null | sort -rh | head -25
Run it with no arguments, and it checks three levels deep. Pass a number, and it goes deeper. Nine times out of ten, the answer is unrotated logs, an old backup someone forgot about, or a stray node_modules directory that somehow made it onto a production server.
3. Checking certificate expiry without a dashboard
Not every site sits behind a fancy monitoring stack, especially smaller client setups. For those, a quick loop over a list of domains tells me exactly how many days are left on each SSL certificate:
#!/bin/bash
# cert-check.sh
while read -r domain; do
expiry=$(echo | openssl s_client -servername "$domain" -connect "$domain:443" 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
days=$(( ($(date -d "$expiry" +%s) - $(date +%s)) / 86400 ))
printf "%-35s %s days\n" "$domain" "$days"
done < domains.txt
I keep a domains.txt per client with one hostname per line and run this monthly. With Let's Encrypt usually handling renewals automatically, this script's real job is catching the edge cases where a background renewal silently failed.
4. Cleaning up logs and journal bloat
systemd's journal and application logs have a way of quietly filling a disk over several months. Before I go hunting for a "mystery" disk usage problem, I run this cleanup script:
#!/bin/bash
# log-cleanup.sh
journalctl --vacuum-time=2weeks
find /var/log -name "*.gz" -mtime +30 -delete
find /var/log -name "*.log.*" -mtime +30 -delete
It is deliberately conservative. Two weeks of journal logs and 30 days of rotated application logs is more than enough for almost any debugging session, while keeping the disk from steadily creeping toward 100%.
Keeping them in one place
All of these live in a small git repository that I clone onto every server I manage:
git clone https://github.com/yourname/server-toolkit /opt/toolkit
ln -s /opt/toolkit/*.sh /usr/local/bin/
The scripts themselves aren't the point. The point is that when something looks off at 11 PM on a server I haven't logged into in months, I am not starting from a blank terminal. I'm running the exact same commands I always run, and that familiarity is worth far more than any of the scripts individually.
Advertisement