Skip to content

Instantly share code, notes, and snippets.

@iconoclasthero
Last active August 20, 2026 23:05
Show Gist options
  • Select an option

  • Save iconoclasthero/66fa7ea58cc934ae400b33d20f27b1de to your computer and use it in GitHub Desktop.

Select an option

Save iconoclasthero/66fa7ea58cc934ae400b33d20f27b1de to your computer and use it in GitHub Desktop.
docker-ps is a colorized, human-readable version of `docker ps`
#!/bin/bash
# ☢=u+2622
: "${TERM:=xterm-256color}"
editscript(){
local scriptpath script path swp; scriptpath=$(realpath "$0" 2>/dev/null); script="${scriptpath##*/}"; path="${scriptpath%/*}"; swp="$path/.$script.swp"
[[ ! -e "$swp" ]] && printf "\n\n%s\n\n" "$swp" && (/usr/bin/nano "$scriptpath") && exit
printf "\n%s is already being edited.\n%s exists; try fg or look in another window.\n" "$scriptpath" "$swp"; exit ;}
pause(){ /dev/tty> read -rp "$*" ; }
[[ "$1" == @(--edit|e|-e) ]] && editscript
[[ "$1" = @(-w|--watch) ]] && { shift; exec watch -c docker-ps "$@"; }
[[ "$1" == @(-f|--full) ]] && shift && printfull=true
# Define colors
tput0="$(tput sgr0)"
bold="$(tput bold)"
ita="$(tput sitm)"
cyan="$(tput setaf 6)"
green="$(tput setaf 2)"
blue="$(tput setaf 4)"
yellow="$(tput setaf 3)"
orange="$(tput setaf 215)"
red="$(tput setaf 9)"
inverse="$(tput setab 7 setaf 0)"
# Header
#printf '%-28s %-30s %-40s %s\n' \
# "${cyan}${bold}CONTAINER ID${tput0}" \
# "${green}${bold}STATUS${tput0}" \
# "${ita}${bold}NAMES${tput0}" \
# "${blue}${bold}IMAGE${tput0}"
# Get docker ps output in JSON format
docker_ps_output=$(docker ps --format '{{json .}}' | jq -s .)
# Parse and print the condensed output with colors
readarray -t tablearr < <(echo "$docker_ps_output" | jq -r '.[] |
(.Size
| capture("(?<num>[0-9.]+)(?<unit>[A-Za-z]+) \\(virtual (?<vnum>[0-9.]+)(?<vunit>[A-Za-z]+)\\)")
) as $sz |
[
.ID,
(.Status
| gsub(" \\(healthy\\)"; "")
| gsub("About a"; "1")
| gsub("Less than a second"; "0 seconds")
| gsub(" +"; " ")
| gsub("\\s+"; " ")
),
.Names,
(.Image | sub(".*/"; "")),
"\($sz.num) \($sz.unit)",
"\($sz.vnum) \($sz.vunit)"
] | @tsv' |
while IFS=$'\t' read -r id status names image size virtsize; do
color_status="$status"
color_line=""
case "$status" in
# *"seconds"*) color_line="${red}" ;;
*"second"*) color_line="${red}"; color_status="${red}${status}${tput0}" ;;
*"Up"*) color_status="${green}${status}${tput0}" ;;
*"Exited"*) color_status="${red}${status}${tput0}" ;;
*) color_status="${yellow}${status}${tput0}" ;;
esac
##"$color_line" doesn't do anything right now.
# printf "${color_line}%-15s %-25s %-25s %-25s${tput0}\n" \
# "${cyan}${id}${tput0}" \
# "${color_status}" \
# "${ita}${names}${tput0}" \
# "${blue}${image}${tput0}"
#
# printf '%s%-15s %-25s %-25s %-25s%s\n' \
# "${color_line}" \
# "${cyan}${id}${tput0}" \
# "${color_status}" \
# "${ita}${names}${tput0}" \
# "${blue}${image}${tput0}" \
# "$tput0"
printf '%s☢%s☢%s☢%s☢%s☢%s☢%s☢%s\n' \
"${color_line}" \
"${cyan}${id}${tput0}" \
"${color_status}" \
"${ita}${names}${tput0}" \
"${blue}${image}${tput0}" \
"${orange}${size}${tput0}" \
"${orange}${virtsize}${tput0}" \
"$tput0"
done)
#printf '☢%s☢%s☢%s☢%s☢%s\n%s\n' \
# "${cyan}${bold}CONTAINER ID${tput0}" \
# "${green}${bold}STATUS${tput0}" \
# "${ita}${bold}NAMES${tput0}" \
# "${blue}${bold}IMAGE${tput0}" \
# "${cyan}${bold}SIZE${tput0}" \
#"$(printf %s\\n "${tablearr[@]}")" |column -t -s ☢ -m
# Colored header variables
NID="${cyan}${bold}CONTAINER ID${tput0}"
NSTATUS="${green}${bold}STATUS${tput0}"
NNAMES="${ita}${bold}NAMES${tput0}"
NIMAGE="${blue}${bold}IMAGE${tput0}"
NSIZE="${orange}${bold}SIZE${tput0}"
NVSIZE="${orange}${bold}VIRT. SIZE${tput0}"
# Print table rows only, headers handled via -N
printf '%s\n' "${tablearr[@]}" | TERM=dumb column -t -s ☢ -N " ","$NID","$NSTATUS","$NNAMES","$NIMAGE","$NSIZE","$NVSIZE" -m -R 6,7
if [[ "$printfull" = true ]]; then
echo
echo
echo "Full ${inverse}$ docker ps${tput0} output:"
# Header
printf "%-15s %-29s %-42s %-42s %-38s %-60s %-20s\n" \
"${cyan}${bold}CONTAINER ID${tput0}" \
"${green}${bold}STATUS${tput0}" \
"${cyan}${bold}NAMES${tput0}" \
"${blue}${bold}IMAGE${tput0}" \
"${yellow}${bold}COMMAND${tput0}" \
"${ita}${bold}CREATED${tput0}" \
"${red}${bold}PORTS${tput0}"
# Get docker ps output
docker ps --format '{{json .}}' | jq -r '
[
.ID,
(.Status | sub(" \\(healthy\\)"; "") | sub("About a"; "1") | sub("Less than a second"; "0 seconds")),
# (.Status | sub(" \\(healthy\\)"; "") | sub("about "; "")),
# (.Status | sub(" \\(healthy\\)"; "")),
.Names,
(.Image | sub(".*/"; "")),
.Command,
# (.Ports | sub("^ +"; "")),
# (.Ports | gsub("\\u003e"; ">") | sub("^ +"; "")), # Replace \u003e with >
# (.Ports | sub("^ +"; "") | gsub("\\u003e"; ">")), # Strip leading spaces and replace \u003e with >
# ((.Ports | sub("^ +"; "") | gsub("\\u003e"; ">")) // "No ports for container"),
(.Ports | select(. != "") | sub("^ +"; "") | gsub("\\u003e"; ">")) // "No ports for container",
(.CreatedAt | sub(" -0400.*"; "") | sub(" -0500.*"; "")) # Strips the time zone information
] | @tsv' | while IFS=$'\t' read -r id status names image command ports created_at; do
color_status="$status"
color_line=""
case "$status" in
*"second"*) color_line="${red}"; color_status="${red}${status}${tput0}" ;;
*"Up"*) color_status="${green}${status}${tput0}" ;;
*"Exited"*) color_status="${red}${status}${tput0}" ;;
*) color_status="${yellow}${status}${tput0}" ;;
esac
# printf "${color_line}%-15s %-25s %-38s %-38s %-36s %-56s %-20s${tput0}\n" \
# "${cyan}${id}${tput0}" \
# "${green}${status}${tput0}" \
# "${cyan}${names}${tput0}" \
# "${blue}${image}${tput0}" \
# "${yellow}${command}${tput0}" \
# "${ita}${created_at}${tput0}" \
# "${red}${ports}${tput0}"
command=${command//…/...}
printf "${color_line}%-15s %-25s %-38s %-38s %-38s %-56s %-20s${tput0}\n" \
"${cyan}${id}${tput0}" \
"${green}${status}${tput0}" \
"${cyan}${names}${tput0}" \
"${blue}${image}${tput0}" \
"${yellow}${command}${tput0}" \
"${ita}${created_at}${tput0}" \
"${red}${ports}${tput0}"
done
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment