Add optional dtop - Docker container monitoring TUI

This commit is contained in:
buildplan 2025-11-06 21:20:56 +00:00
parent 103abb8d1d
commit ff6bcc97ec

View File

@ -1,8 +1,10 @@
#!/bin/bash
# Debian and Ubuntu Server Hardening Interactive Script
# Version: 0.73 | 2025-10-22
# Version: 0.74 | 2025-11-06
# Changelog:
# - v0.74: Add optional dtop (https://github.com/amir20/dtop) after docker installation.
#. Update .bashrc
# - v0.73: Revised/improved logic in .bashrc for memory and system updates.
# - v0.72: Added configure_custom_bashrc() function that creates and installs a feature-rich .bashrc file during user creation.
# - v0.71: Simplify test backup function to work reliably with Hetzner storagebox
@ -77,7 +79,7 @@
set -euo pipefail
# --- Update Configuration ---
CURRENT_VERSION="0.73"
CURRENT_VERSION="0.74"
SCRIPT_URL="https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh"
CHECKSUM_URL="${SCRIPT_URL}.sha256"
@ -228,7 +230,7 @@ print_header() {
printf '%s\n' "${CYAN}╔═════════════════════════════════════════════════════════════════╗${NC}"
printf '%s\n' "${CYAN}║ ║${NC}"
printf '%s\n' "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${NC}"
printf '%s\n' "${CYAN}║ v0.73 | 2025-10-22${NC}"
printf '%s\n' "${CYAN}║ v0.74 | 2025-11-06${NC}"
printf '%s\n' "${CYAN}║ ║${NC}"
printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
printf '\n'
@ -1238,16 +1240,15 @@ __bash_prompt_command() {
PROMPT_COMMAND=__bash_prompt_command
# --- Editor Configuration ---
# Set default editor with fallback chain.
if command -v vim &>/dev/null; then
export EDITOR=vim
export VISUAL=vim
elif command -v vi &>/dev/null; then
export EDITOR=vi
export VISUAL=vi
else
elif command -v nano &>/dev/null; then
export EDITOR=nano
export VISUAL=nano
else
export EDITOR=vi
export VISUAL=vi
fi
# --- Additional Environment Variables ---
@ -1265,7 +1266,7 @@ mkcd() {
# Create a backup of a file with timestamp.
backup() {
if [ -f "$1" ]; then
local backup_file="$1.backup-$(date +%Y%m%d-%H%M%S)"
local backup_file; backup_file="$1.backup-$(date +%Y%m%d-%H%M%S)"
cp "$1" "$backup_file"
echo "Backup created: $backup_file"
else
@ -1278,19 +1279,19 @@ backup() {
extract() {
if [ -f "$1" ]; then
case "$1" in
*.tar.bz2) tar xjf "$1" ;;
*.tar.gz) tar xzf "$1" ;;
*.tar.xz) tar xJf "$1" ;;
*.bz2) bunzip2 "$1" ;;
*.rar) unrar x "$1" ;;
*.gz) gunzip "$1" ;;
*.tar) tar xf "$1" ;;
*.tbz2) tar xjf "$1" ;;
*.tgz) tar xzf "$1" ;;
*.zip) unzip "$1" ;;
*.Z) uncompress "$1" ;;
*.7z) 7z x "$1" ;;
*.deb) ar x "$1" ;;
*.tar.bz2) tar xjf "$1" ;;
*.tar.gz) tar xzf "$1" ;;
*.tar.xz) tar xJf "$1" ;;
*.bz2) bunzip2 "$1" ;;
*.rar) unrar x "$1" ;;
*.gz) gunzip "$1" ;;
*.tar) tar xf "$1" ;;
*.tbz2) tar xjf "$1" ;;
*.tgz) tar xzf "$1" ;;
*.zip) unzip "$1" ;;
*.Z) uncompress "$1" ;;
*.7z) 7z x "$1" ;;
*.deb) ar x "$1" ;;
*.tar.zst)
if command -v zstd &>/dev/null; then
zstd -dc "$1" | tar xf -
@ -1300,7 +1301,7 @@ extract() {
;;
*)
echo "'$1' cannot be extracted via extract()" >&2
return 1
return 1 # Add return 1 for consistency
;;
esac
else
@ -1334,6 +1335,9 @@ ftext() {
grep -rnw . -e "$1" 2>/dev/null
}
# Search history easily
hgrep() { history | grep -i --color=auto "$@"; }
# Create a tarball of a directory.
targz() {
if [ -d "$1" ]; then
@ -1357,7 +1361,36 @@ sizeof() {
# Show most used commands from history.
histop() {
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n20
history | awk -v ig="$HISTIGNORE" 'BEGIN{OFS="\t";gsub(/:/,"|",ig);ir="^("ig")($| )";sr="(^|\\s)\\./"}
{cmd=$4;for(i=5;i<=NF;i++)cmd=cmd" "$i}
(cmd==""||cmd~ir||cmd~sr){next}
{C[cmd]++;t++}
END{if(t>0)for(a in C)printf"%d\t%.2f%%\t%s\n",C[a],(C[a]/t*100),a}' |
sort -nr | head -n20 |
awk 'BEGIN{
FS="\t";
maxc=length("COUNT");
maxp=length("PERCENT");
}
{
data[NR]=$0;
len1=length($1);
len2=length($2);
if(len1>maxc)maxc=len1;
if(len2>maxp)maxp=len2;
}
END{
fmt=" %-4s %-*s %-*s %s\n";
printf fmt,"RANK",maxc,"COUNT",maxp,"PERCENT","COMMAND";
sep_c=sep_p="";
for(i=1;i<=maxc;i++)sep_c=sep_c"-";
for(i=1;i<=maxp;i++)sep_p=sep_p"-";
printf fmt,"----",maxc,sep_c,maxp,sep_p,"-------";
for(i=1;i<=NR;i++){
split(data[i],f,"\t");
printf fmt,i".",maxc,f[1],maxp,f[2],f[3]
}
}'
}
# Quick server info display
@ -1392,18 +1425,45 @@ sysinfo() {
cpu_info=$(lscpu | awk -F: '/Model name/ {print $2; exit}' | xargs || grep -m1 'model name' /proc/cpuinfo | cut -d ':' -f2 | xargs)
[ -z "$cpu_info" ] && cpu_info="Unknown"
# --- IP Detection (preferred interfaces first) ---
local ip_addr
for iface in eth0 wlan0 ens33 eno1 enp0s3 enp3s0; do
# --- IP Detection ---
local ip_addr public_ipv4 public_ipv6
# Try to get public IPv4 first
public_ipv4=$(curl -4 -s -m 2 --connect-timeout 1 https://checkip.amazonaws.com 2>/dev/null || \
curl -4 -s -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
curl -4 -s -m 2 --connect-timeout 1 https://api.ipify.org 2>/dev/null)
# If no IPv4, try IPv6
if [ -z "$public_ipv4" ]; then
public_ipv6=$(curl -6 -s -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
curl -6 -s -m 2 --connect-timeout 1 https://icanhazip.co 2>/dev/null || \
curl -6 -s -m 2 --connect-timeout 1 https://api64.ipify.org 2>/dev/null)
fi
# Get local/internal IP as fallback
for iface in eth0 ens3 enp0s3 enp0s6 wlan0 ens33 eno1; do
ip_addr=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
[ -n "$ip_addr" ] && break
done
[ -z "$ip_addr" ] && ip_addr=$(ip -4 addr show scope global | awk '/inet/ {print $2}' | cut -d/ -f1 | head -n1)
[ -z "$ip_addr" ] && ip_addr=$(ip -4 addr show scope global 2>/dev/null | awk '/inet/ {print $2}' | cut -d/ -f1 | head -n1)
# --- System Info ---
if [ -n "$ip_addr" ]; then
if [ -n "$public_ipv4" ]; then
# Show public IPv4 (preferred)
printf "${CYAN}%-15s${RESET} %s ${YELLOW}[%s]${RESET}" "Hostname:" "$(hostname)" "$public_ipv4"
# Show local IP if different from public
if [ -n "$ip_addr" ] && [ "$ip_addr" != "$public_ipv4" ]; then
printf " ${DIM}(local: %s)${RESET}\n" "$ip_addr"
else
printf "\n"
fi
elif [ -n "$public_ipv6" ]; then
# Show public IPv6 if no IPv4
printf "${CYAN}%-15s${RESET} %s ${YELLOW}[%s]${RESET}" "Hostname:" "$(hostname)" "$public_ipv6"
[ -n "$ip_addr" ] && printf " ${DIM}(local: %s)${RESET}\n" "$ip_addr" || printf "\n"
elif [ -n "$ip_addr" ]; then
# Show local IP only
printf "${CYAN}%-15s${RESET} %s ${YELLOW}[%s]${RESET}\n" "Hostname:" "$(hostname)" "$ip_addr"
else
# No IP detected
printf "${CYAN}%-15s${RESET} %s\n" "Hostname:" "$(hostname)"
fi
printf "${CYAN}%-15s${RESET} %s\n" "OS:" "$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2 || echo 'Unknown')"
@ -1424,7 +1484,7 @@ sysinfo() {
if [ -f /var/run/reboot-required ]; then
printf "${CYAN}%-15s${RESET} ${BOLD_RED}⚠ REBOOT REQUIRED${RESET}\n" "System:"
[ -s /var/run/reboot-required.pkgs ] && \
printf " ${DIM}Reason:${RESET} %s\n" "$(paste -sd ' ' /var/run/reboot-required.pkgs)"
printf " ${DIM}Reason:${RESET} %s\n" "$(paste -sd ' ' /var/run/reboot-required.pkgs)"
fi
# --- Available Updates (APT) ---
@ -1439,19 +1499,23 @@ sysinfo() {
security="${apt_check_output##*;}"
fi
fi
# Fallback if apt-check didn't provide values
if [ -z "$total" ] && [ -r /var/lib/update-notifier/updates-available ]; then
total=$(awk '/[0-9]+ (update|package)s? can be (updated|applied|installed)/ {print $1; exit}' /var/lib/update-notifier/updates-available 2>/dev/null)
security=$(awk '/[0-9]+ (update|package)s? .*security/ {print $1; exit}' /var/lib/update-notifier/updates-available 2>/dev/null)
fi
# Final fallback
if [ -z "$total" ]; then
total=$(apt list --upgradable 2>/dev/null | grep -c upgradable)
security=$(apt list --upgradable 2>/dev/null | grep -ci security)
fi
total="${total:-0}"
security="${security:-0}"
# Display updates if available
if [ -n "$total" ] && [ "$total" -gt 0 ] 2>/dev/null; then
printf "${CYAN}%-15s${RESET} " "Updates:"
if [ -n "$security" ] && [ "$security" -gt 0 ] 2>/dev/null; then
@ -1466,11 +1530,11 @@ sysinfo() {
security_list=$(printf "%s\n" "${upgradable_all[@]}" | grep -i security | head -n5 | awk -F/ '{print $1}')
[ -n "$upgradable_list" ] && \
printf " ${DIM}Upgradable:${RESET} %s" "$(echo "$upgradable_list" | paste -sd ', ')"
printf " ${DIM}Upgradable:${RESET} %s" "$(echo "$upgradable_list" | paste -sd ', ')"
[ "$total" -gt 5 ] && printf " ... (+%s more)\n" $((total - 5)) || printf "\n"
[ -n "$security_list" ] && \
printf " ${YELLOW}Security:${RESET} %s" "$(echo "$security_list" | paste -sd ', ')"
printf " ${YELLOW}Security:${RESET} %s" "$(echo "$security_list" | paste -sd ', ')"
[ "$security" -gt 5 ] && printf " ... (+%s more)\n" $((security - 5)) || printf "\n"
fi
fi
@ -1485,6 +1549,28 @@ sysinfo() {
fi
fi
# --- Tailscale Info (if installed and connected) ---
if command -v tailscale &>/dev/null; then
local ts_ipv4 ts_ipv6 ts_hostname
# Get Tailscale IPs
ts_ipv4=$(tailscale ip -4 2>/dev/null)
ts_ipv6=$(tailscale ip -6 2>/dev/null)
# Only show if connected
if [ -n "$ts_ipv4" ] || [ -n "$ts_ipv6" ]; then
# Get hostname from status (FIXED: use head -n1 to get only first line)
ts_hostname=$(tailscale status --self --peers=false 2>/dev/null | head -n1 | awk '{print $2}')
printf "${CYAN}%-15s${RESET} " "Tailscale:"
printf "${GREEN}Connected${RESET}"
[ -n "$ts_ipv4" ] && printf " - %s" "$ts_ipv4"
[ -n "$ts_hostname" ] && printf " ${DIM}(%s)${RESET}" "$ts_hostname"
printf "\n"
# Optional: Show IPv6 on second line if available
if [ -n "$ts_ipv6" ]; then
printf " ${DIM}IPv6: %s${RESET}\n" "$ts_ipv6"
fi
fi
fi
printf "\n"
}
@ -1501,6 +1587,47 @@ checkupdates() {
fi
}
# Disk space alert (warns if any partition > 80%)
diskcheck() {
df -h | awk '
NR > 1 {
usage = $5
gsub(/%/, "", usage)
if (usage > 80) {
printf "⚠️ %s\n", $0
found = 1
}
}
END {
if (!found) print "✓ All disks below 80%"
}
'
}
# Directory bookmarks
export MARKPATH=$HOME/.marks
[ -d "$MARKPATH" ] || mkdir -p "$MARKPATH"
mark() { ln -sfn "$(pwd)" "$MARKPATH/${1:-$(basename "$PWD")}"; }
jump() { cd -P "$MARKPATH/$1" 2>/dev/null || ls -l "$MARKPATH"; }
# Service status shortcut (cleaner output)
svc() { sudo systemctl status "$1" --no-pager -l | head -20; }
alias failed='systemctl --failed --no-pager'
# Show top 10 processes by CPU
topcpu() { ps aux --sort=-%cpu | head -11; }
# Show top 10 processes by memory
topmem() { ps aux --sort=-%mem | head -11; }
# Network connections summary
netsum() {
echo "=== Active Connections ==="
ss -s
echo -e "\n=== Listening Ports ==="
sudo ss -tulnp | grep LISTEN | awk '{print $5, $7}' | sort -u
}
# --- Aliases ---
# Enable color support for common commands.
if [ -x /usr/bin/dircolors ]; then
@ -1519,9 +1646,12 @@ fi
alias ll='ls -alFh'
alias la='ls -A'
alias l='ls -CF'
alias lt='ls -alFht' # Sort by modification time, newest first
alias ltr='ls -alFhtr' # Sort by modification time, oldest first
alias lS='ls -alFhS' # Sort by size, largest first
alias lt='ls -alFht' # Sort by modification time, newest first
alias ltr='ls -alFhtr' # Sort by modification time, oldest first
alias lS='ls -alFhS' # Sort by size, largest first
# Last command with sudo
alias please='sudo $(history -p !!)'
# Safety aliases to prompt before overwriting.
alias rm='rm -i'
@ -1534,7 +1664,7 @@ alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'
alias -- -='cd -' # Go to previous directory
alias -- -='cd -' # Go to previous directory
alias ~='cd ~'
alias h='history'
alias c='clear'
@ -1582,6 +1712,7 @@ alias myip='curl -s ifconfig.me || curl -s icanhazip.com' # Alternatives: api.ip
localip() {
ip -4 addr | awk '/inet/ {print $2}' | cut -d/ -f1 | grep -v '127.0.0.1'
}
alias netstat='ss'
alias ping='ping -c 5'
alias fastping='ping -c 100 -i 0.2'
@ -1635,12 +1766,14 @@ if command -v docker &>/dev/null; then
# Docker stats
alias dstats='docker stats --no-stream'
alias dstatsa='docker stats'
dtop() {
dst() {
docker stats --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}'
}
# Safe stop all (shows command instead of executing)
alias dstopall='echo "To stop all containers, run: docker stop \$(docker ps -q)"'
alias dstopa='echo "To stop all containers, run: docker stop \$(docker ps -q)"'
# Start all stopped containers
alias dstarta='docker start $(docker ps -aq)'
# Docker Compose v2 aliases (check if the compose plugin exists)
if docker compose version &>/dev/null; then
@ -1816,11 +1949,11 @@ fi
# Enable programmable completion features.
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
# shellcheck disable=SC1091
. /usr/share/bash-completion/bash_completion
# shellcheck disable=SC1091
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
# shellcheck disable=SC1091
. /etc/bash_completion
# shellcheck disable=SC1091
. /etc/bash_completion
fi
fi
@ -1861,7 +1994,7 @@ bashhelp() {
cat << 'HELPTEXT'
╔════════════════════════════════════════════════════════╗
║ .bashrc - Quick Reference
.bashrc - Quick Reference ║
╚════════════════════════════════════════════════════════╝
Usage: bashhelp [category]
@ -1870,179 +2003,194 @@ Categories: navigation, files, system, docker, git, network
═══════════════════════════════════════════════════════════════════
📁 NAVIGATION & DIRECTORY
═══════════════════════════════════════════════════════════════════
.. Go up one directory
... Go up two directories
.... Go up three directories
..... Go up four directories
- Go to previous directory
~ Go to home directory
.. Go up one directory
... Go up two directories
.... Go up three directories
..... Go up four directories
- Go to previous directory
~ Go to home directory
mkcd <dir> Create directory and cd into it
up <n> Go up N directories (e.g., up 3)
path Display PATH variable (one per line)
mkcd <dir> Create directory and cd into it
up <n> Go up N directories (e.g., up 3)
path Display PATH variable (one per line)
mark <name> Bookmark current directory
jump <name> Jump to a bookmarked directory
═══════════════════════════════════════════════════════════════════
📄 FILE OPERATIONS
═══════════════════════════════════════════════════════════════════
ll List all files with details (human-readable)
la List all files including hidden
l List files in column format
lt List by time, newest first
ltr List by time, oldest first
lS List by size, largest first
lsd List only directories
lsf List only files
ll List all files with details (human-readable)
la List all files including hidden
l List files in column format
lt List by time, newest first
ltr List by time, oldest first
lS List by size, largest first
lsd List only directories
lsf List only files
ff <name> Find files by name (case-insensitive)
fd <name> Find directories by name (case-insensitive)
ftext <text> Search for text in files recursively
ff <name> Find files by name (case-insensitive)
fd <name> Find directories by name (case-insensitive)
ftext <text> Search for text in files recursively
extract <file> Extract any archive (tar, zip, 7z, etc.)
targz <dir> Create tar.gz of directory
backup <file> Create timestamped backup of file
extract <file> Extract any archive (tar, zip, 7z, etc.)
targz <dir> Create tar.gz of directory
backup <file> Create timestamped backup of file
sizeof <path> Get size of file or directory
duh [path] Disk usage sorted by size
count Count files in current directory
cpv <src> <dst> Copy with progress bar (rsync)
sizeof <path> Get size of file or directory
duh [path] Disk usage sorted by size
count Count files in current directory
cpv <src> <dst> Copy with progress bar (rsync)
═══════════════════════════════════════════════════════════════════
💻 SYSTEM & MONITORING
═══════════════════════════════════════════════════════════════════
sysinfo Display comprehensive system information
checkupdates Check for available system updates
sysinfo Display comprehensive system information
checkupdates Check for available system updates
diskcheck Check for disk partitions over 80%
psgrep <pat> Search for process by name
psmem Show top 10 processes by memory usage
pscpu Show top 10 processes by CPU usage
top10 Show top 10 memory-consuming processes
psgrep <pat> Search for process by name
topcpu Show top 10 processes by CPU
topmem Show top 10 processes by Memory
pscpu Show top 10 processes by CPU (tree view)
psmem Show top 10 processes by Memory (tree view)
ports Show all listening ports (TCP/UDP)
listening Show listening ports with process info
meminfo Display detailed memory information
ports Show all listening ports (TCP/UDP)
listening Show listening ports with process info
meminfo Display detailed memory information
h Show command history
histop Show most used commands
reload Reload bashrc configuration
h Show command history
hgrep <pat> Search command history
histop Show most used commands
c, cls Clear the screen
reload Reload bashrc configuration
═══════════════════════════════════════════════════════════════════
🐳 DOCKER & DOCKER COMPOSE
═══════════════════════════════════════════════════════════════════
Docker Commands:
d docker (shortcut)
dps List running containers
dpsa List all containers
di List images
dv List volumes
dn List networks
dex <id> Execute interactive shell in container
dlog <id> Follow container logs
d docker (shortcut)
dps List running containers
dpsa List all containers
di List images
dv List volumes
dn List networks
dex <id> Execute interactive shell in container
dlog <id> Follow container logs
dsh <id> Enter container shell (bash/sh)
dip [id] Show container IP addresses
dsize Show disk usage by containers
dbinds [id] Show bind mounts for containers
denv <id> Show environment variables
dfollow <id> Follow logs with tail (default 100 lines)
dsh <id> Enter container shell (bash/sh)
dip [id] Show container IP addresses
dsize Show disk usage by containers
dbinds [id] Show bind mounts for containers
denv <id> Show environment variables
dfollow <id> Follow logs with tail (default 100 lines)
dstats Container stats snapshot
dstatsa Container stats live
dtop Container stats formatted table
dstats Container stats snapshot
dstatsa Container stats live
dst Container stats formatted table
dprune Prune system (remove unused data)
dprunea Prune all (including images)
dvprune Prune unused volumes
diprune Prune unused images
drmall Remove all stopped containers
dprune Prune system (remove unused data)
dprunea Prune all (including images)
dvprune Prune unused volumes
diprune Prune unused images
drmall Remove all stopped containers
Docker Compose:
dc docker compose (shortcut)
dcup Start services in background
dcdown Stop and remove services
dclogs Follow compose logs
dcps List compose services
dcex <srv> Execute command in service
dcsh <srv> Enter service shell (bash/sh)
dc docker compose (shortcut)
dcup Start services in background
dcdown Stop and remove services
dclogs Follow compose logs
dcps List compose services
dcex <srv> Execute command in service
dcsh <srv> Enter service shell (bash/sh)
dcbuild Build services
dcbn Build with no cache
dcrestart Restart services
dcrecreate Recreate services
dcpull Pull service images
dcstop Stop services
dcstart Start services
dcbuild Build services
dcbn Build with no cache
dcrestart Restart services
dcrecreate Recreate services
dcpull Pull service images
dcstop Stop services
dcstart Start services
dcstatus Show service status & resource usage
dcreload <srv> Restart service and follow logs
dcupdate <srv> Pull, restart service, follow logs
dcstatus Show service status & resource usage
dcreload <srv> Restart service and follow logs
dcupdate <srv> Pull, restart service, follow logs
dcgrep <srv> <pattern> Filter service logs
dcconfig Show resolved compose configuration
dcvalidate Validate compose file syntax
dcconfig Show resolved compose configuration
dcvalidate Validate compose file syntax
═══════════════════════════════════════════════════════════════════
🔀 GIT SHORTCUTS
═══════════════════════════════════════════════════════════════════
gs git status
ga git add
gc git commit
gp git push
gl git log (graph view)
gd git diff
gb git branch
gco git checkout
gs git status
ga git add
gc git commit
gp git push
gl git log (graph view)
gd git diff
gb git branch
gco git checkout
═══════════════════════════════════════════════════════════════════
🌐 NETWORK
═══════════════════════════════════════════════════════════════════
myip Show external IP address
localip Show local IP address(es)
ping Ping with 5 packets (default)
fastping Fast ping (100 packets, 0.2s interval)
netstat Show network connections (ss)
myip Show external IP address
localip Show local IP address(es)
netsum Network connections summary
kssh SSH wrapper for kitty terminal
ping Ping with 5 packets (default)
fastping Fast ping (100 packets, 0.2s interval)
netstat Show network connections (ss)
═══════════════════════════════════════════════════════════════════
⚙️ SYSTEM ADMINISTRATION
═══════════════════════════════════════════════════════════════════
Systemd:
sysstart <srv> Start service
sysstop <srv> Stop service
sysrestart <srv> Restart service
sysstatus <srv> Show service status
sysenable <srv> Enable service
sysdisable <srv> Disable service
sysreload Reload systemd daemon
svc <srv> Show service status (brief)
failed List failed systemd services
sysstart <srv> Start service
sysstop <srv> Stop service
sysrestart <srv> Restart service
sysstatus <srv> Show service status
sysenable <srv> Enable service
sysdisable <srv> Disable service
sysreload Reload systemd daemon
APT (Debian/Ubuntu):
aptup Update and upgrade packages
aptin <pkg> Install package
aptrm <pkg> Remove package
aptsearch <term> Search for packages
aptshow <pkg> Show package information
aptclean Remove unused packages
aptlist List installed packages
aptup Update and upgrade packages
aptin <pkg> Install package
aptrm <pkg> Remove package
aptsearch <term> Search for packages
aptshow <pkg> Show package information
aptclean Remove unused packages
aptlist List installed packages
Sudo:
please Run last command with sudo
═══════════════════════════════════════════════════════════════════
🕒 DATE & TIME
═══════════════════════════════════════════════════════════════════
now Current date and time (YYYY-MM-DD HH:MM:SS)
nowdate Current date (YYYY-MM-DD)
timestamp Unix timestamp
now Current date and time (YYYY-MM-DD HH:MM:SS)
nowdate Current date (YYYY-MM-DD)
timestamp Unix timestamp
═══════════════════════════════════════════════════════════════════
HELP & INFORMATION
═══════════════════════════════════════════════════════════════════
bashhelp Show this help (all categories)
bashhelp Show this help (all categories)
bh Alias for bashhelp
commands List all custom functions and aliases
bashhelp navigation Show navigation commands only
bashhelp files Show file operation commands
bashhelp system Show system monitoring commands
bashhelp docker Show docker commands only
bashhelp git Show git shortcuts
bashhelp network Show network commands
bashhelp files Show file operation commands
bashhelp system Show system monitoring commands
bashhelp docker Show docker commands only
bashhelp git Show git shortcuts
bashhelp network Show network commands
═══════════════════════════════════════════════════════════════════
💡 TIP: Most commands support --help or -h for more information
The prompt shows: ✗ for failed commands, git branch when in repo
The prompt shows: ✗ for failed commands, (git branch) when in repo
HELPTEXT
;;
@ -2052,21 +2200,24 @@ HELPTEXT
═══ NAVIGATION & DIRECTORY COMMANDS ═══
.. Go up one directory
... Go up two directories
.... Go up three directories
..... Go up four directories
- Go to previous directory
~ Go to home directory
.. Go up one directory
... Go up two directories
.... Go up three directories
..... Go up four directories
- Go to previous directory
~ Go to home directory
mkcd <dir> Create directory and cd into it
up <n> Go up N directories
path Display PATH variable
mkcd <dir> Create directory and cd into it
up <n> Go up N directories
path Display PATH variable
mark <name> Bookmark current directory
jump <name> Jump to a bookmarked directory
Examples:
mkcd ~/projects/newapp # Create and enter directory
up 3 # Go up 3 levels
cd - # Return to previous directory
mkcd ~/projects/newapp # Create and enter directory
up 3 # Go up 3 levels
mark proj1 # Bookmark current dir as 'proj1'
jump proj1 # Jump back to 'proj1'
HELPTEXT
;;
@ -2080,23 +2231,23 @@ Listing:
ll, la, l, lt, ltr, lS, lsd, lsf
Finding:
ff <name> Find files by name
fd <name> Find directories by name
ftext <text> Search text in files
ff <name> Find files by name
fd <name> Find directories by name
ftext <text> Search text in files
Archives:
extract <file> Extract any archive type
targz <dir> Create tar.gz archive
backup <file> Create timestamped backup
extract <file> Extract any archive type
targz <dir> Create tar.gz archive
backup <file> Create timestamped backup
Size Info:
sizeof <path> Get size of file/directory
duh [path] Disk usage sorted by size
count Count files in directory
cpv Copy with progress (rsync)
sizeof <path> Get size of file/directory
duh [path] Disk usage sorted by size
count Count files in directory
cpv Copy with progress (rsync)
Examples:
ff README # Find files named *README*
ff README # Find files named *README*
extract data.tar.gz
backup ~/.bashrc
@ -2109,27 +2260,31 @@ HELPTEXT
═══ SYSTEM MONITORING COMMANDS ═══
Overview:
sysinfo Comprehensive system info
checkupdates Check for package updates
sysinfo Comprehensive system info
checkupdates Check for package updates
diskcheck Check for disks > 80%
Processes:
psgrep <pat> Search processes
psmem Top 10 by memory
pscpu Top 10 by CPU
top10 Top memory consumers
psgrep <pat> Search processes
topcpu Top 10 by CPU
topmem Top 10 by Memory
pscpu Top 10 by CPU (tree view)
psmem Top 10 by Memory (tree view)
Network:
ports Listening ports
listening Ports with process info
ports Listening ports
listening Ports with process info
Memory:
meminfo Detailed memory info
free Free memory (human-readable)
meminfo Detailed memory info
free Free memory (human-readable)
History:
h Show history
histop Most used commands
reload Reload bashrc
Shell:
h Show history
hgrep <pat> Search history
histop Most used commands
c, cls Clear screen
reload Reload bashrc
Examples:
psgrep nginx
@ -2147,26 +2302,26 @@ Basic:
dps, dpsa, di, dv, dn, dex, dlog
Management:
dsh <id> Enter container shell
dip [id] Show IP addresses
dsize Show disk usage
dbinds [id] Show bind mounts
denv <id> Show environment variables
dfollow <id> Follow logs
dsh <id> Enter container shell
dip [id] Show IP addresses
dsize Show disk usage
dbinds [id] Show bind mounts
denv <id> Show environment variables
dfollow <id> Follow logs
Stats & Cleanup:
dstats, dstatsa, dtop
dstats, dstatsa, dst
dprune, dprunea, dvprune, diprune
drmall Remove stopped containers
drmall Remove stopped containers
Docker Compose:
dcup, dcdown, dclogs, dcps, dcex, dcsh
dcbuild, dcrestart, dcrecreate
dcstatus Status & resource usage
dcreload <srv> Restart & follow logs
dcupdate <srv> Pull & update service
dcgrep <srv> <p> Filter logs
dcvalidate Validate compose file
dcstatus Status & resource usage
dcreload <srv> Restart & follow logs
dcupdate <srv> Pull & update service
dcgrep <s> <p> Filter logs
dcvalidate Validate compose file
Examples:
dsh mycontainer
@ -2182,20 +2337,20 @@ HELPTEXT
═══ GIT SHORTCUTS ═══
gs git status
ga git add
gc git commit
gp git push
gl git log (graph)
gd git diff
gb git branch
gco git checkout
gs git status
ga git add
gc git commit
gp git push
gl git log (graph)
gd git diff
gb git branch
gco git checkout
Examples:
gs # Check status
ga . # Add all changes
gc -m "Update docs" # Commit
gp # Push to remote
gs # Check status
ga . # Add all changes
gc -m "Update docs" # Commit
gp # Push to remote
HELPTEXT
;;
@ -2205,16 +2360,18 @@ HELPTEXT
═══ NETWORK COMMANDS ═══
myip Show external IP
localip Show local IP(s)
ports Show listening ports
listening Ports with process info
ping Ping (5 packets)
fastping Fast ping (100 packets)
netstat Network connections
myip Show external IP
localip Show local IP(s)
netsum Network connection summary
kssh SSH wrapper for kitty
ports Show listening ports
listening Ports with process info
ping Ping (5 packets)
fastping Fast ping (100 packets)
netstat Network connections (ss)
Examples:
myip # Get public IP
myip # Get public IP
listening | grep 80
ping google.com
@ -2231,6 +2388,7 @@ HELPTEXT
}
# Preserve Bash's builtin `help` while integrating bashhelp
# This wrapper routes custom help to bashhelp, bash builtins to builtin help
help() {
case "${1:-}" in
""|all|navigation|files|system|docker|git|network)
@ -3680,6 +3838,68 @@ EOF
fi
print_warning "NOTE: '$USERNAME' must log out and back in to use Docker without sudo."
log "Docker installation completed."
# Offer dtop installation
install_dtop_optional
}
install_dtop_optional() {
if sudo sh -c 'command -v dtop' >/dev/null 2>&1 || command -v dtop >/dev/null 2>&1; then
print_info "dtop is already installed."
return 0
fi
if ! confirm "Install 'dtop' (Docker container monitoring TUI)?"; then
print_info "Skipping dtop installation."
return 0
fi
print_info "Installing dtop for user '$USERNAME'..."
local DTOP_INSTALLER="/tmp/dtop-installer.sh"
if ! curl -fsSL "https://github.com/amir20/dtop/releases/latest/download/dtop-installer.sh" -o "$DTOP_INSTALLER"; then
print_warning "Failed to download dtop installer. Continuing setup..."
log "Failed to download dtop installer."
return 0
fi
chmod +x "$DTOP_INSTALLER"
trap 'rm -f "$DTOP_INSTALLER"' RETURN
local USER_HOME
USER_HOME=$(getent passwd "$USERNAME" | cut -d: -f6)
local USER_LOCAL_BIN="$USER_HOME/.local/bin"
if [[ ! -d "$USER_LOCAL_BIN" ]]; then
print_info "Creating $USER_LOCAL_BIN..."
if ! sudo -u "$USERNAME" mkdir -p "$USER_LOCAL_BIN"; then
print_warning "Failed to create $USER_LOCAL_BIN. Skipping dtop."
return 0
fi
fi
if sudo -u "$USERNAME" bash "$DTOP_INSTALLER" < /dev/null >> "$LOG_FILE" 2>&1; then
# Verify installation
if [[ -f "$USER_LOCAL_BIN/dtop" ]]; then
sudo -u "$USERNAME" chmod +x "$USER_LOCAL_BIN/dtop"
local BASHRC="$USER_HOME/.bashrc"
if [[ -f "$BASHRC" ]] && ! grep -q "\.local/bin" "$BASHRC"; then
print_info "Adding ~/.local/bin to PATH in $BASHRC..."
{
echo ''
echo '# Add local bin to PATH'
# shellcheck disable=SC2016
echo 'if [ -d "$HOME/.local/bin" ]; then PATH="$HOME/.local/bin:$PATH"; fi'
} >> "$BASHRC"
chown "$USERNAME:$USERNAME" "$BASHRC"
if grep -q "\.local/bin" "$BASHRC"; then
print_info "PATH configuration updated successfully."
else
print_warning "Failed to update PATH, but dtop is still installed."
fi
fi
print_success "dtop installed successfully to $USER_LOCAL_BIN."
log "dtop installed to $USER_LOCAL_BIN for user $USERNAME"
else
print_warning "dtop installer finished, but binary not found at $USER_LOCAL_BIN/dtop"
log "dtop binary missing after user installation attempt."
fi
else
print_warning "dtop installation script failed. Continuing setup..."
log "dtop installation script failed."
fi
}
install_tailscale() {