Skip to content

Instantly share code, notes, and snippets.

@gnyman
Created March 15, 2023 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnyman/f634a0a449bbcf8f7a92b29b10f7f6f7 to your computer and use it in GitHub Desktop.
Save gnyman/f634a0a449bbcf8f7a92b29b10f7f6f7 to your computer and use it in GitHub Desktop.
Show memory usage of commands you run in terminal, including sub processes and even supports pipes
#!/bin/bash
# this script allows you to monitor the memory usage of a command like
# mmmon.sh "docker save my/image:0.1 | xdelta3 -d -s /dev/stdin delta-0.1-to-0.2.xdelta /dev/stdout | docker load"
# the ""'s are important
# it will include any child processes
# it will handle ctrl+c and forward it
# I couldn't find this anywhere else, hope someone finds it useful
# - Gabriel
# licence: public domain
# Check if a complex command is provided
if [ -z "$1" ]; then
echo "Usage: $0 'complex-command'"
exit 1
fi
# Function to forward the SIGINT signal to subprocesses
forward_sigint() {
for pid in $(echo "$all_pids" | tr ',' ' '); do
kill -s SIGINT "$pid" 2>/dev/null
done
exit 0
}
# Run the complex command in the background
eval "$1 &"
# Get the PID of the most recent background command
PID=$!
# Set up the trap to handle the SIGINT signal
trap forward_sigint SIGINT
# Function to get all related PIDs
get_related_pids() {
local pids="$1"
local new_pids="$(pgrep -P $(echo "$pids" | tr '\n' ',' | sed 's/,$//') | tr '\n' ' ')"
echo "$pids $new_pids"
}
# Monitor memory usage of the PID and its children
while kill -0 "$PID" 2>/dev/null; do
echo "Monitoring memory usage (PID, PPID, COMMAND, %MEM, RSS):"
pids="$(get_related_pids "$PID")"
siblings="$(pgrep -s "$(ps -o sid= -p "$PID")")"
all_pids="$(echo "$pids $siblings" | tr ' ' '\n' | sort -u | tr '\n' ',' | sed 's/,$//'| sed 's/^,//')"
ps_output=$(ps -o pid,ppid,comm,%mem,rss --forest -p "$all_pids" | grep -vE '^ *$|^ *PID')
echo "$ps_output"
echo "-------------------------"
total_memory=$(echo "$ps_output" | awk '{sum += $5} END {print sum}')
echo "Total memory (RSS): $total_memory"
echo "-------------------------"
sleep 1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment