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 #!/bin/bash
# Debian and Ubuntu Server Hardening Interactive Script # Debian and Ubuntu Server Hardening Interactive Script
# Version: 0.73 | 2025-10-22 # Version: 0.74 | 2025-11-06
# Changelog: # 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.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.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 # - v0.71: Simplify test backup function to work reliably with Hetzner storagebox
@ -77,7 +79,7 @@
set -euo pipefail set -euo pipefail
# --- Update Configuration --- # --- 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" SCRIPT_URL="https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh"
CHECKSUM_URL="${SCRIPT_URL}.sha256" 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}║ ║${NC}" printf '%s\n' "${CYAN}║ ║${NC}"
printf '%s\n' "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${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 '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}" printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
printf '\n' printf '\n'
@ -1238,16 +1240,15 @@ __bash_prompt_command() {
PROMPT_COMMAND=__bash_prompt_command PROMPT_COMMAND=__bash_prompt_command
# --- Editor Configuration --- # --- Editor Configuration ---
# Set default editor with fallback chain.
if command -v vim &>/dev/null; then if command -v vim &>/dev/null; then
export EDITOR=vim export EDITOR=vim
export VISUAL=vim export VISUAL=vim
elif command -v vi &>/dev/null; then elif command -v nano &>/dev/null; then
export EDITOR=vi
export VISUAL=vi
else
export EDITOR=nano export EDITOR=nano
export VISUAL=nano export VISUAL=nano
else
export EDITOR=vi
export VISUAL=vi
fi fi
# --- Additional Environment Variables --- # --- Additional Environment Variables ---
@ -1265,7 +1266,7 @@ mkcd() {
# Create a backup of a file with timestamp. # Create a backup of a file with timestamp.
backup() { backup() {
if [ -f "$1" ]; then 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" cp "$1" "$backup_file"
echo "Backup created: $backup_file" echo "Backup created: $backup_file"
else else
@ -1278,19 +1279,19 @@ backup() {
extract() { extract() {
if [ -f "$1" ]; then if [ -f "$1" ]; then
case "$1" in case "$1" in
*.tar.bz2) tar xjf "$1" ;; *.tar.bz2) tar xjf "$1" ;;
*.tar.gz) tar xzf "$1" ;; *.tar.gz) tar xzf "$1" ;;
*.tar.xz) tar xJf "$1" ;; *.tar.xz) tar xJf "$1" ;;
*.bz2) bunzip2 "$1" ;; *.bz2) bunzip2 "$1" ;;
*.rar) unrar x "$1" ;; *.rar) unrar x "$1" ;;
*.gz) gunzip "$1" ;; *.gz) gunzip "$1" ;;
*.tar) tar xf "$1" ;; *.tar) tar xf "$1" ;;
*.tbz2) tar xjf "$1" ;; *.tbz2) tar xjf "$1" ;;
*.tgz) tar xzf "$1" ;; *.tgz) tar xzf "$1" ;;
*.zip) unzip "$1" ;; *.zip) unzip "$1" ;;
*.Z) uncompress "$1" ;; *.Z) uncompress "$1" ;;
*.7z) 7z x "$1" ;; *.7z) 7z x "$1" ;;
*.deb) ar x "$1" ;; *.deb) ar x "$1" ;;
*.tar.zst) *.tar.zst)
if command -v zstd &>/dev/null; then if command -v zstd &>/dev/null; then
zstd -dc "$1" | tar xf - zstd -dc "$1" | tar xf -
@ -1300,7 +1301,7 @@ extract() {
;; ;;
*) *)
echo "'$1' cannot be extracted via extract()" >&2 echo "'$1' cannot be extracted via extract()" >&2
return 1 return 1 # Add return 1 for consistency
;; ;;
esac esac
else else
@ -1334,6 +1335,9 @@ ftext() {
grep -rnw . -e "$1" 2>/dev/null grep -rnw . -e "$1" 2>/dev/null
} }
# Search history easily
hgrep() { history | grep -i --color=auto "$@"; }
# Create a tarball of a directory. # Create a tarball of a directory.
targz() { targz() {
if [ -d "$1" ]; then if [ -d "$1" ]; then
@ -1357,7 +1361,36 @@ sizeof() {
# Show most used commands from history. # Show most used commands from history.
histop() { 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 # 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) 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" [ -z "$cpu_info" ] && cpu_info="Unknown"
# --- IP Detection (preferred interfaces first) --- # --- IP Detection ---
local ip_addr local ip_addr public_ipv4 public_ipv6
for iface in eth0 wlan0 ens33 eno1 enp0s3 enp3s0; do
# 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) ip_addr=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
[ -n "$ip_addr" ] && break [ -n "$ip_addr" ] && break
done 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 --- # --- 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" printf "${CYAN}%-15s${RESET} %s ${YELLOW}[%s]${RESET}\n" "Hostname:" "$(hostname)" "$ip_addr"
else else
# No IP detected
printf "${CYAN}%-15s${RESET} %s\n" "Hostname:" "$(hostname)" printf "${CYAN}%-15s${RESET} %s\n" "Hostname:" "$(hostname)"
fi fi
printf "${CYAN}%-15s${RESET} %s\n" "OS:" "$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2 || echo 'Unknown')" 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 if [ -f /var/run/reboot-required ]; then
printf "${CYAN}%-15s${RESET} ${BOLD_RED}⚠ REBOOT REQUIRED${RESET}\n" "System:" printf "${CYAN}%-15s${RESET} ${BOLD_RED}⚠ REBOOT REQUIRED${RESET}\n" "System:"
[ -s /var/run/reboot-required.pkgs ] && \ [ -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 fi
# --- Available Updates (APT) --- # --- Available Updates (APT) ---
@ -1439,19 +1499,23 @@ sysinfo() {
security="${apt_check_output##*;}" security="${apt_check_output##*;}"
fi fi
fi fi
# Fallback if apt-check didn't provide values # Fallback if apt-check didn't provide values
if [ -z "$total" ] && [ -r /var/lib/update-notifier/updates-available ]; then 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) 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) security=$(awk '/[0-9]+ (update|package)s? .*security/ {print $1; exit}' /var/lib/update-notifier/updates-available 2>/dev/null)
fi fi
# Final fallback # Final fallback
if [ -z "$total" ]; then if [ -z "$total" ]; then
total=$(apt list --upgradable 2>/dev/null | grep -c upgradable) total=$(apt list --upgradable 2>/dev/null | grep -c upgradable)
security=$(apt list --upgradable 2>/dev/null | grep -ci security) security=$(apt list --upgradable 2>/dev/null | grep -ci security)
fi fi
total="${total:-0}" total="${total:-0}"
security="${security:-0}" security="${security:-0}"
# Display updates if available
if [ -n "$total" ] && [ "$total" -gt 0 ] 2>/dev/null; then if [ -n "$total" ] && [ "$total" -gt 0 ] 2>/dev/null; then
printf "${CYAN}%-15s${RESET} " "Updates:" printf "${CYAN}%-15s${RESET} " "Updates:"
if [ -n "$security" ] && [ "$security" -gt 0 ] 2>/dev/null; then 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}') security_list=$(printf "%s\n" "${upgradable_all[@]}" | grep -i security | head -n5 | awk -F/ '{print $1}')
[ -n "$upgradable_list" ] && \ [ -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" [ "$total" -gt 5 ] && printf " ... (+%s more)\n" $((total - 5)) || printf "\n"
[ -n "$security_list" ] && \ [ -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" [ "$security" -gt 5 ] && printf " ... (+%s more)\n" $((security - 5)) || printf "\n"
fi fi
fi fi
@ -1485,6 +1549,28 @@ sysinfo() {
fi fi
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" printf "\n"
} }
@ -1501,6 +1587,47 @@ checkupdates() {
fi 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 --- # --- Aliases ---
# Enable color support for common commands. # Enable color support for common commands.
if [ -x /usr/bin/dircolors ]; then if [ -x /usr/bin/dircolors ]; then
@ -1519,9 +1646,12 @@ fi
alias ll='ls -alFh' alias ll='ls -alFh'
alias la='ls -A' alias la='ls -A'
alias l='ls -CF' alias l='ls -CF'
alias lt='ls -alFht' # Sort by modification time, newest first alias lt='ls -alFht' # Sort by modification time, newest first
alias ltr='ls -alFhtr' # Sort by modification time, oldest first alias ltr='ls -alFhtr' # Sort by modification time, oldest first
alias lS='ls -alFhS' # Sort by size, largest 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. # Safety aliases to prompt before overwriting.
alias rm='rm -i' alias rm='rm -i'
@ -1534,7 +1664,7 @@ alias ..='cd ..'
alias ...='cd ../..' alias ...='cd ../..'
alias ....='cd ../../..' alias ....='cd ../../..'
alias .....='cd ../../../..' alias .....='cd ../../../..'
alias -- -='cd -' # Go to previous directory alias -- -='cd -' # Go to previous directory
alias ~='cd ~' alias ~='cd ~'
alias h='history' alias h='history'
alias c='clear' alias c='clear'
@ -1582,6 +1712,7 @@ alias myip='curl -s ifconfig.me || curl -s icanhazip.com' # Alternatives: api.ip
localip() { localip() {
ip -4 addr | awk '/inet/ {print $2}' | cut -d/ -f1 | grep -v '127.0.0.1' ip -4 addr | awk '/inet/ {print $2}' | cut -d/ -f1 | grep -v '127.0.0.1'
} }
alias netstat='ss' alias netstat='ss'
alias ping='ping -c 5' alias ping='ping -c 5'
alias fastping='ping -c 100 -i 0.2' alias fastping='ping -c 100 -i 0.2'
@ -1635,12 +1766,14 @@ if command -v docker &>/dev/null; then
# Docker stats # Docker stats
alias dstats='docker stats --no-stream' alias dstats='docker stats --no-stream'
alias dstatsa='docker stats' alias dstatsa='docker stats'
dtop() { dst() {
docker stats --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}' docker stats --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}'
} }
# Safe stop all (shows command instead of executing) # 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) # Docker Compose v2 aliases (check if the compose plugin exists)
if docker compose version &>/dev/null; then if docker compose version &>/dev/null; then
@ -1816,11 +1949,11 @@ fi
# Enable programmable completion features. # Enable programmable completion features.
if ! shopt -oq posix; then if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then if [ -f /usr/share/bash-completion/bash_completion ]; then
# shellcheck disable=SC1091 # shellcheck disable=SC1091
. /usr/share/bash-completion/bash_completion . /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then elif [ -f /etc/bash_completion ]; then
# shellcheck disable=SC1091 # shellcheck disable=SC1091
. /etc/bash_completion . /etc/bash_completion
fi fi
fi fi
@ -1861,7 +1994,7 @@ bashhelp() {
cat << 'HELPTEXT' cat << 'HELPTEXT'
╔════════════════════════════════════════════════════════╗ ╔════════════════════════════════════════════════════════╗
║ .bashrc - Quick Reference .bashrc - Quick Reference ║
╚════════════════════════════════════════════════════════╝ ╚════════════════════════════════════════════════════════╝
Usage: bashhelp [category] Usage: bashhelp [category]
@ -1870,179 +2003,194 @@ Categories: navigation, files, system, docker, git, network
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
📁 NAVIGATION & DIRECTORY 📁 NAVIGATION & DIRECTORY
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
.. Go up one directory .. Go up one directory
... Go up two directories ... Go up two directories
.... Go up three directories .... Go up three directories
..... Go up four directories ..... Go up four directories
- Go to previous directory - Go to previous directory
~ Go to home directory ~ Go to home directory
mkcd <dir> Create directory and cd into it mkcd <dir> Create directory and cd into it
up <n> Go up N directories (e.g., up 3) up <n> Go up N directories (e.g., up 3)
path Display PATH variable (one per line) path Display PATH variable (one per line)
mark <name> Bookmark current directory
jump <name> Jump to a bookmarked directory
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
📄 FILE OPERATIONS 📄 FILE OPERATIONS
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
ll List all files with details (human-readable) ll List all files with details (human-readable)
la List all files including hidden la List all files including hidden
l List files in column format l List files in column format
lt List by time, newest first lt List by time, newest first
ltr List by time, oldest first ltr List by time, oldest first
lS List by size, largest first lS List by size, largest first
lsd List only directories lsd List only directories
lsf List only files lsf List only files
ff <name> Find files by name (case-insensitive) ff <name> Find files by name (case-insensitive)
fd <name> Find directories by name (case-insensitive) fd <name> Find directories by name (case-insensitive)
ftext <text> Search for text in files recursively ftext <text> Search for text in files recursively
extract <file> Extract any archive (tar, zip, 7z, etc.) extract <file> Extract any archive (tar, zip, 7z, etc.)
targz <dir> Create tar.gz of directory targz <dir> Create tar.gz of directory
backup <file> Create timestamped backup of file backup <file> Create timestamped backup of file
sizeof <path> Get size of file or directory sizeof <path> Get size of file or directory
duh [path] Disk usage sorted by size duh [path] Disk usage sorted by size
count Count files in current directory count Count files in current directory
cpv <src> <dst> Copy with progress bar (rsync) cpv <src> <dst> Copy with progress bar (rsync)
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
💻 SYSTEM & MONITORING 💻 SYSTEM & MONITORING
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
sysinfo Display comprehensive system information sysinfo Display comprehensive system information
checkupdates Check for available system updates checkupdates Check for available system updates
diskcheck Check for disk partitions over 80%
psgrep <pat> Search for process by name psgrep <pat> Search for process by name
psmem Show top 10 processes by memory usage topcpu Show top 10 processes by CPU
pscpu Show top 10 processes by CPU usage topmem Show top 10 processes by Memory
top10 Show top 10 memory-consuming processes 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) ports Show all listening ports (TCP/UDP)
listening Show listening ports with process info listening Show listening ports with process info
meminfo Display detailed memory information meminfo Display detailed memory information
h Show command history h Show command history
histop Show most used commands hgrep <pat> Search command history
reload Reload bashrc configuration histop Show most used commands
c, cls Clear the screen
reload Reload bashrc configuration
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
🐳 DOCKER & DOCKER COMPOSE 🐳 DOCKER & DOCKER COMPOSE
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
Docker Commands: Docker Commands:
d docker (shortcut) d docker (shortcut)
dps List running containers dps List running containers
dpsa List all containers dpsa List all containers
di List images di List images
dv List volumes dv List volumes
dn List networks dn List networks
dex <id> Execute interactive shell in container dex <id> Execute interactive shell in container
dlog <id> Follow container logs dlog <id> Follow container logs
dsh <id> Enter container shell (bash/sh) dsh <id> Enter container shell (bash/sh)
dip [id] Show container IP addresses dip [id] Show container IP addresses
dsize Show disk usage by containers dsize Show disk usage by containers
dbinds [id] Show bind mounts for containers dbinds [id] Show bind mounts for containers
denv <id> Show environment variables denv <id> Show environment variables
dfollow <id> Follow logs with tail (default 100 lines) dfollow <id> Follow logs with tail (default 100 lines)
dstats Container stats snapshot dstats Container stats snapshot
dstatsa Container stats live dstatsa Container stats live
dtop Container stats formatted table dst Container stats formatted table
dprune Prune system (remove unused data) dprune Prune system (remove unused data)
dprunea Prune all (including images) dprunea Prune all (including images)
dvprune Prune unused volumes dvprune Prune unused volumes
diprune Prune unused images diprune Prune unused images
drmall Remove all stopped containers drmall Remove all stopped containers
Docker Compose: Docker Compose:
dc docker compose (shortcut) dc docker compose (shortcut)
dcup Start services in background dcup Start services in background
dcdown Stop and remove services dcdown Stop and remove services
dclogs Follow compose logs dclogs Follow compose logs
dcps List compose services dcps List compose services
dcex <srv> Execute command in service dcex <srv> Execute command in service
dcsh <srv> Enter service shell (bash/sh) dcsh <srv> Enter service shell (bash/sh)
dcbuild Build services dcbuild Build services
dcbn Build with no cache dcbn Build with no cache
dcrestart Restart services dcrestart Restart services
dcrecreate Recreate services dcrecreate Recreate services
dcpull Pull service images dcpull Pull service images
dcstop Stop services dcstop Stop services
dcstart Start services dcstart Start services
dcstatus Show service status & resource usage dcstatus Show service status & resource usage
dcreload <srv> Restart service and follow logs dcreload <srv> Restart service and follow logs
dcupdate <srv> Pull, restart service, follow logs dcupdate <srv> Pull, restart service, follow logs
dcgrep <srv> <pattern> Filter service logs dcgrep <srv> <pattern> Filter service logs
dcconfig Show resolved compose configuration dcconfig Show resolved compose configuration
dcvalidate Validate compose file syntax dcvalidate Validate compose file syntax
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
🔀 GIT SHORTCUTS 🔀 GIT SHORTCUTS
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
gs git status gs git status
ga git add ga git add
gc git commit gc git commit
gp git push gp git push
gl git log (graph view) gl git log (graph view)
gd git diff gd git diff
gb git branch gb git branch
gco git checkout gco git checkout
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
🌐 NETWORK 🌐 NETWORK
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
myip Show external IP address myip Show external IP address
localip Show local IP address(es) localip Show local IP address(es)
ping Ping with 5 packets (default) netsum Network connections summary
fastping Fast ping (100 packets, 0.2s interval) kssh SSH wrapper for kitty terminal
netstat Show network connections (ss) ping Ping with 5 packets (default)
fastping Fast ping (100 packets, 0.2s interval)
netstat Show network connections (ss)
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
⚙️ SYSTEM ADMINISTRATION ⚙️ SYSTEM ADMINISTRATION
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
Systemd: Systemd:
sysstart <srv> Start service svc <srv> Show service status (brief)
sysstop <srv> Stop service failed List failed systemd services
sysrestart <srv> Restart service sysstart <srv> Start service
sysstatus <srv> Show service status sysstop <srv> Stop service
sysenable <srv> Enable service sysrestart <srv> Restart service
sysdisable <srv> Disable service sysstatus <srv> Show service status
sysreload Reload systemd daemon sysenable <srv> Enable service
sysdisable <srv> Disable service
sysreload Reload systemd daemon
APT (Debian/Ubuntu): APT (Debian/Ubuntu):
aptup Update and upgrade packages aptup Update and upgrade packages
aptin <pkg> Install package aptin <pkg> Install package
aptrm <pkg> Remove package aptrm <pkg> Remove package
aptsearch <term> Search for packages aptsearch <term> Search for packages
aptshow <pkg> Show package information aptshow <pkg> Show package information
aptclean Remove unused packages aptclean Remove unused packages
aptlist List installed packages aptlist List installed packages
Sudo:
please Run last command with sudo
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
🕒 DATE & TIME 🕒 DATE & TIME
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
now Current date and time (YYYY-MM-DD HH:MM:SS) now Current date and time (YYYY-MM-DD HH:MM:SS)
nowdate Current date (YYYY-MM-DD) nowdate Current date (YYYY-MM-DD)
timestamp Unix timestamp timestamp Unix timestamp
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
HELP & INFORMATION 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 navigation Show navigation commands only
bashhelp files Show file operation commands bashhelp files Show file operation commands
bashhelp system Show system monitoring commands bashhelp system Show system monitoring commands
bashhelp docker Show docker commands only bashhelp docker Show docker commands only
bashhelp git Show git shortcuts bashhelp git Show git shortcuts
bashhelp network Show network commands bashhelp network Show network commands
═══════════════════════════════════════════════════════════════════ ═══════════════════════════════════════════════════════════════════
💡 TIP: Most commands support --help or -h for more information 💡 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 HELPTEXT
;; ;;
@ -2052,21 +2200,24 @@ HELPTEXT
═══ NAVIGATION & DIRECTORY COMMANDS ═══ ═══ NAVIGATION & DIRECTORY COMMANDS ═══
.. Go up one directory .. Go up one directory
... Go up two directories ... Go up two directories
.... Go up three directories .... Go up three directories
..... Go up four directories ..... Go up four directories
- Go to previous directory - Go to previous directory
~ Go to home directory ~ Go to home directory
mkcd <dir> Create directory and cd into it mkcd <dir> Create directory and cd into it
up <n> Go up N directories up <n> Go up N directories
path Display PATH variable path Display PATH variable
mark <name> Bookmark current directory
jump <name> Jump to a bookmarked directory
Examples: Examples:
mkcd ~/projects/newapp # Create and enter directory mkcd ~/projects/newapp # Create and enter directory
up 3 # Go up 3 levels up 3 # Go up 3 levels
cd - # Return to previous directory mark proj1 # Bookmark current dir as 'proj1'
jump proj1 # Jump back to 'proj1'
HELPTEXT HELPTEXT
;; ;;
@ -2080,23 +2231,23 @@ Listing:
ll, la, l, lt, ltr, lS, lsd, lsf ll, la, l, lt, ltr, lS, lsd, lsf
Finding: Finding:
ff <name> Find files by name ff <name> Find files by name
fd <name> Find directories by name fd <name> Find directories by name
ftext <text> Search text in files ftext <text> Search text in files
Archives: Archives:
extract <file> Extract any archive type extract <file> Extract any archive type
targz <dir> Create tar.gz archive targz <dir> Create tar.gz archive
backup <file> Create timestamped backup backup <file> Create timestamped backup
Size Info: Size Info:
sizeof <path> Get size of file/directory sizeof <path> Get size of file/directory
duh [path] Disk usage sorted by size duh [path] Disk usage sorted by size
count Count files in directory count Count files in directory
cpv Copy with progress (rsync) cpv Copy with progress (rsync)
Examples: Examples:
ff README # Find files named *README* ff README # Find files named *README*
extract data.tar.gz extract data.tar.gz
backup ~/.bashrc backup ~/.bashrc
@ -2109,27 +2260,31 @@ HELPTEXT
═══ SYSTEM MONITORING COMMANDS ═══ ═══ SYSTEM MONITORING COMMANDS ═══
Overview: Overview:
sysinfo Comprehensive system info sysinfo Comprehensive system info
checkupdates Check for package updates checkupdates Check for package updates
diskcheck Check for disks > 80%
Processes: Processes:
psgrep <pat> Search processes psgrep <pat> Search processes
psmem Top 10 by memory topcpu Top 10 by CPU
pscpu Top 10 by CPU topmem Top 10 by Memory
top10 Top memory consumers pscpu Top 10 by CPU (tree view)
psmem Top 10 by Memory (tree view)
Network: Network:
ports Listening ports ports Listening ports
listening Ports with process info listening Ports with process info
Memory: Memory:
meminfo Detailed memory info meminfo Detailed memory info
free Free memory (human-readable) free Free memory (human-readable)
History: Shell:
h Show history h Show history
histop Most used commands hgrep <pat> Search history
reload Reload bashrc histop Most used commands
c, cls Clear screen
reload Reload bashrc
Examples: Examples:
psgrep nginx psgrep nginx
@ -2147,26 +2302,26 @@ Basic:
dps, dpsa, di, dv, dn, dex, dlog dps, dpsa, di, dv, dn, dex, dlog
Management: Management:
dsh <id> Enter container shell dsh <id> Enter container shell
dip [id] Show IP addresses dip [id] Show IP addresses
dsize Show disk usage dsize Show disk usage
dbinds [id] Show bind mounts dbinds [id] Show bind mounts
denv <id> Show environment variables denv <id> Show environment variables
dfollow <id> Follow logs dfollow <id> Follow logs
Stats & Cleanup: Stats & Cleanup:
dstats, dstatsa, dtop dstats, dstatsa, dst
dprune, dprunea, dvprune, diprune dprune, dprunea, dvprune, diprune
drmall Remove stopped containers drmall Remove stopped containers
Docker Compose: Docker Compose:
dcup, dcdown, dclogs, dcps, dcex, dcsh dcup, dcdown, dclogs, dcps, dcex, dcsh
dcbuild, dcrestart, dcrecreate dcbuild, dcrestart, dcrecreate
dcstatus Status & resource usage dcstatus Status & resource usage
dcreload <srv> Restart & follow logs dcreload <srv> Restart & follow logs
dcupdate <srv> Pull & update service dcupdate <srv> Pull & update service
dcgrep <srv> <p> Filter logs dcgrep <s> <p> Filter logs
dcvalidate Validate compose file dcvalidate Validate compose file
Examples: Examples:
dsh mycontainer dsh mycontainer
@ -2182,20 +2337,20 @@ HELPTEXT
═══ GIT SHORTCUTS ═══ ═══ GIT SHORTCUTS ═══
gs git status gs git status
ga git add ga git add
gc git commit gc git commit
gp git push gp git push
gl git log (graph) gl git log (graph)
gd git diff gd git diff
gb git branch gb git branch
gco git checkout gco git checkout
Examples: Examples:
gs # Check status gs # Check status
ga . # Add all changes ga . # Add all changes
gc -m "Update docs" # Commit gc -m "Update docs" # Commit
gp # Push to remote gp # Push to remote
HELPTEXT HELPTEXT
;; ;;
@ -2205,16 +2360,18 @@ HELPTEXT
═══ NETWORK COMMANDS ═══ ═══ NETWORK COMMANDS ═══
myip Show external IP myip Show external IP
localip Show local IP(s) localip Show local IP(s)
ports Show listening ports netsum Network connection summary
listening Ports with process info kssh SSH wrapper for kitty
ping Ping (5 packets) ports Show listening ports
fastping Fast ping (100 packets) listening Ports with process info
netstat Network connections ping Ping (5 packets)
fastping Fast ping (100 packets)
netstat Network connections (ss)
Examples: Examples:
myip # Get public IP myip # Get public IP
listening | grep 80 listening | grep 80
ping google.com ping google.com
@ -2231,6 +2388,7 @@ HELPTEXT
} }
# Preserve Bash's builtin `help` while integrating bashhelp # Preserve Bash's builtin `help` while integrating bashhelp
# This wrapper routes custom help to bashhelp, bash builtins to builtin help
help() { help() {
case "${1:-}" in case "${1:-}" in
""|all|navigation|files|system|docker|git|network) ""|all|navigation|files|system|docker|git|network)
@ -3680,6 +3838,68 @@ EOF
fi fi
print_warning "NOTE: '$USERNAME' must log out and back in to use Docker without sudo." print_warning "NOTE: '$USERNAME' must log out and back in to use Docker without sudo."
log "Docker installation completed." 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() { install_tailscale() {