Created
July 20, 2018 17:11
-
-
Save deardooley/011ce72d1e2ad3c03045879f0ea41b25 to your computer and use it in GitHub Desktop.
Some extra CLI sugar to make working with the Docker command line a bit less painful. Curated from around the web and extended with prompts, regex matching and extra aliases and shortcuts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Use these in your .dotfiles to help make Docker more manageable | |
#alias dip='dmachine ip 2> /dev/null' | |
alias drund="docker run -d -P" | |
alias drun="docker run -t -i -P" | |
alias dimg="di" | |
alias dexec='dx' | |
alias dc='docker-compose' | |
# portable xargs, handles the missing support for -r|--no-run-if-empty | |
# on non-gnu implementations of xarts | |
function gxargs() { | |
is_gnu=$(xargs -r 2>&1 >> /dev/null) | |
if (( $? )); then | |
stdin=$(cat <&0) | |
if [[ $1 == "-r" ]] || [[ $1 == "--no-run-if-empty" ]] | |
then | |
# shift the arguments to get rid of the "-r" that is not valid on OSX | |
shift | |
# wc -l return some whitespaces, let's get rid of them with tr | |
linecount=$(echo $stdin | grep -v "^$" | wc -l | tr -d '[:space:]') | |
if [ "x$linecount" = "x0" ] | |
then | |
exit 0 | |
fi | |
fi | |
# grep returns an error code for no matching lines, so only activate error checks from here | |
set -e | |
set -o pipefail | |
echo $stdin | xargs $@ | |
else | |
echo $stdin | xargs $@ | |
fi | |
} | |
function dmachine() { | |
if [[ -z "$2" ]]; then | |
dm_vm=default | |
else | |
dm_vm="$2" | |
fi | |
docker-machine $1 ${dm_vm} | |
} | |
# Build an image with the given name/tag using the Dockerfile in the | |
# current directory | |
function dbuild() { docker build -t="$1" .; } | |
# handles ouptut formatting | |
function dockererror() { | |
unset containername; | |
# Detect whether output is piped or not. | |
if [[ -t 1 ]]; then | |
printf '%b\n' "\033[1;31m${@}\033[0m" | |
else | |
print $@ | |
fi | |
} >&2 | |
function di() { | |
if [[ -z "$1" ]]; then | |
dimagelike all | sed -e $'s# #\\\n#g' | grep -v "^REPOSITORY:TAG" | |
else | |
dimagelike $1 | sed -e $'s# #\\\n#g' | grep -v "^REPOSITORY:TAG" | |
fi | |
} | |
# | |
# Display tags for an image | |
# | |
function ditags { | |
for Repo in $* ; do | |
if [[ -z $( echo "$Repo" | grep "/" ) ]]; then | |
fullRepo="library/$Repo" | |
else | |
fullRepo="$Repo" | |
fi | |
curl -s -S "https://registry.hub.docker.com/v2/repositories/$fullRepo/tags/" | \ | |
python -mjson.tool | \ | |
sed -e 's#,#,\n#g' -e 's#\[#\[\n#g' | \ | |
grep '"name"' | \ | |
awk -F\" '{print $4;}' | \ | |
sort -fu | \ | |
sed -e "s#^#${Repo}:#" | |
done | |
} | |
# Stop one or more running containers. If none are provided, you will | |
# be promped with a list of containers. | |
function dstop() { | |
# if the user does not provide a container, let them pick one | |
dwhich $1 | |
if [[ -z "$containername" ]]; then | |
dockererror "Please specify one or more containers to stop."; return 1; | |
fi | |
docker stop $containername; | |
} | |
function dtail() { | |
# if the user does not provide a container, let them pick one | |
dwhich $1 | |
docker logs --tail=100 -f $containername | |
} | |
function dcbounce { | |
if [[ -z "$@" ]]; then | |
dc stop | |
dc rm -f | |
dc up -d | |
else | |
for i in "${@}"; do | |
dc stop "$i" | |
dc rm -f "$i" | |
dc up -d "$i" | |
done | |
fi | |
} | |
function dcabounce { | |
if [[ -z "$@" ]]; then | |
dca stop | |
dca rm -f | |
dca up -d | |
else | |
for i in "${@}"; do | |
dca stop "$i" | |
dca rm -f "$i" | |
dca up -d "$i" | |
done | |
fi | |
} | |
function dcbbounce { | |
if [[ -z "$@" ]]; then | |
dcb stop | |
dcb rm -f | |
dcb up -d | |
else | |
for i in "${@}"; do | |
dcb stop "$i" | |
dcb rm -f "$i" | |
dcb up -d "$i" | |
done | |
fi | |
} | |
function dbounce { | |
docker restart "$@" | |
} | |
function dps() { | |
if [[ -z "$1" ]] | |
then | |
dwhich all | |
elif [ "$#" -eq 1 ] && [ "$1" == "-a" ] | |
then | |
dwhich -a all | |
else | |
dwhich "$@" | |
fi | |
} | |
# Remove one or more stopped containers. If none are provided, you will | |
# be promped with a list of containers. | |
function drm() { | |
# if the user does not provide a container, let them pick one | |
dwhich "$@" '-a' | |
if [[ -z "$containername" ]]; then | |
dockererror "Please specify one or more containers to remove."; return 1; | |
fi | |
docker rm $containername; | |
} | |
# Remove one or more images. If none are provided, you will be promped | |
# with a list of images. Partial matches and regex are supported. | |
function drmi() { | |
# if the user does not provide an image, let them pick one | |
imagename=$(dimagelike "$@") | |
if [[ -z "$imagename" ]]; then | |
dockererror "Please specify one or more partial image names and/or versions to remove or all to remove all images"; return 1; | |
fi | |
docker rmi "$imagename"; | |
} | |
# Docker exec into a container | |
function dx() { | |
# if the user does not provide a container, let them pick one | |
dwhich "$1" | |
if [[ -z "$containername" ]]; then | |
dockererror "Please select a valid container to exec."; return 1; | |
# if the user does not provide a container, or argument, just run the default command | |
elif [[ -z "$1" ]]; then | |
docker exec -i -t $containername $2; | |
# pop the container name from the argument list and run the rest as the command | |
else | |
shift | |
docker exec -i -t $containername "$@"; | |
fi | |
} | |
# Does a basic docker exec into a container's bash shell. If the container name isn't provided | |
# the user is promted for the container name from a list. | |
function dbash() { | |
dwhich "$1" | |
if [[ -z "$containername" ]]; then | |
dockererror "Please select a valid container to exec."; return 1; | |
else | |
dx "$containername" '/bin/bash'; | |
fi | |
} | |
# Does a basic docker exec into a container's shell. If the container name isn't provided | |
# the user is promted for the container name from a list. | |
function dsh() { | |
dwhich "$1" | |
if [[ -z "$containername" ]]; then | |
dockererror "Please select a valid container to exec."; return 1; | |
else | |
dx "$containername" 'sh'; | |
fi | |
} | |
# Display realtime info for one or more running containers. If none | |
# are provided, you will be promped with a list of images. Partial | |
# matches and regex are supported. | |
function dstats() { | |
# if the user does not provide an image, let them pick one | |
dwhich "$@" | |
if [ -z "$containername" ]; then | |
docker stats $(echo $(dps)) | |
else | |
docker stats $(echo $containername) | |
fi | |
} | |
# removes all untagged images | |
function dtidy() { | |
docker images | grep "^<none>" | awk '{print $3}' | gxargs --no-run-if-empty docker rmi | |
} | |
# Smokes every container removes every untagged image | |
function dclean() { | |
docker ps -aq | gxargs --no-run-if-empty docker rm -f | |
docker images | grep "^<none>" | awk '{print $3}' | gxargs --no-run-if-empty docker rmi | |
} | |
# Smokes every container and every tagged image | |
function dnuke() { | |
docker ps -aq | gxargs --no-run-if-empty docker kill | |
docker ps -aq | gxargs --no-run-if-empty docker rm -f | |
docker images -q | gxargs --no-run-if-empty docker rmi -f | |
} | |
function dlog() { | |
# if the user does not provide an image, let them pick one | |
dwhich "$@" | |
if [ -z "$containername" ]; then | |
dockererror "Please specify one or more containers for which to display realtime stats."; return 1; | |
fi | |
docker logs --tail=500 -f $containername | |
} | |
# validates a user-supplied container name. If none is supplied | |
# the user is prompted to select from a list of containers on the current system | |
function dwhich() { | |
containername='' | |
INCLUDE_STOPPED='' | |
if [[ "$#" == "0" ]] | |
then | |
# nothing to do here | |
INCLUDE_STOPPED='' | |
else | |
iter=1 | |
for i in "$@" | |
do | |
if [[ '-a' == "$i" ]] | |
then | |
INCLUDE_STOPPED="-a" | |
shift | |
#else | |
# echo -e "leaving argument $i in place\n" | |
fi | |
iter="$[iter+1]" | |
done | |
fi | |
containerids=( $(docker ps $INCLUDE_STOPPED | grep -v '^CONTAINER' | awk '{print $NF}') ) | |
if [[ -z "$1" ]]; then | |
for i in "${!containerids[@]}" | |
do | |
echo "[$i] ${containerids[$i]}" | |
done | |
echo -n "Select container(s) []: " | |
eval "read containerresponse" | |
containerresponse=( $containerresponse ) | |
else | |
containerresponse=( "$@" ) | |
fi | |
re='^[0-9]+$' | |
# if empty, none was provided and none was selected | |
if [[ -z "$containerresponse" ]]; then | |
dockererror "Unknown container name. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1; | |
else | |
for i in "${!containerresponse[@]}" | |
do | |
# validate the numeric selection | |
if [[ "${containerresponse[$i]}" =~ $re ]] ; then | |
if [ ${containerresponse[$i]} -ge ${#containerids[@]} ]; then | |
dockererror "Invalid choice. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1; | |
else | |
containername=$(echo -e "${containerids[${containerresponse[$i]}]}\n${containername}") | |
# echo "${containername}" | |
fi | |
# return all containers | |
elif [ "all" == "${containerresponse[$i]}" ] || [ "*" == "${containerresponse[$i]}" ]; then | |
containername="${containerids[@]}" | |
#echo "${containername}" | |
# validate the provided value | |
else | |
containermatches=$(docker ps $INCLUDE_STOPPED | grep -v '^CONTAINER' | awk '{print $NF}' | grep "${containerresponse[$i]}") | |
if [[ -n "$containermatches" ]]; then | |
foundmatching=1 | |
containername=$(echo -e "${containermatches}\n$containername") | |
#echo "${containername}" | |
else | |
dockererror "Unknown container name ${containerresponse[$i]}. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1; | |
fi | |
#for i in "${!containerids[@]}" | |
#do | |
# if [[ "$containername" == "${containerids[$i]}" ]]; then | |
# foundmatch=1 | |
# containername="${containerids[$i]}" | |
# break | |
# fi | |
#done | |
#if [ -z "$foundmatch" ]; then | |
# dockererror "Unknown container name. Please select a valid number from 1-${#containerids[@]} or provide a valid container name."; return 1; | |
#fi | |
fi | |
done | |
# print results | strip duplicates | reverse and delete empty newlines | replace spaces with newlines | |
echo "${containername}" | awk '!a[$0]++' | sed -ne '1!G;h;$p' | tr " " "\n" | |
fi | |
#echo "$containername" | |
} | |
# validates a user-supplied image name and/or version based on partial match. If none is supplied | |
# the user is prompted to select from a list of images on the current system | |
function dimagelike() { | |
imagenames=( $(docker images | grep -v '^<none>' | awk '{print $1,":",$2; }' | sed -e 's# ##g') ) | |
if [[ -z "$1" ]]; then | |
for i in "${!imagenames[@]}" | |
do | |
echo "[$i] ${imagenames[$i]}" | |
done | |
echo -n "Select imag(e) []: " | |
eval "read selectedimage" | |
else | |
selectedimage="$1" | |
fi | |
re='^[0-9]+$' | |
# if empty, none was provided and none was selected | |
if [[ -z "$selectedimage" ]]; then | |
dockererror "Please provide an image name and/or version or select a valid number from 1-${#imagenames[@]}. Partial names and wildcards are supported."; return 1; | |
# validate the numeric selection | |
elif [[ "$selectedimage" =~ $re ]] ; then | |
if [ $selectedimage -ge ${#imagenames[@]} ]; then | |
dockererror "Invalid choice. Please provide an image name and/or version or select a valid number from 1-${#imagenames[@]}. Partial names and wildcards are supported."; return 1; | |
else | |
echo "${imagenames[$selectedimage]}" | |
fi | |
# return all containers | |
elif [ "all" == "$selectedimage" ] || [ "*" == "$selectedimage" ]; then | |
echo "${imagenames[@]}" | |
# validate the provided value | |
else | |
# selectedimage=( "${selectedimage[@]}" ) | |
# for j in "${#selectedimage[@]}" | |
# do | |
# match the selected value against the existing image name and tag | |
imgmatches=$(docker images | grep -v '^<none>' | awk '{print $1,":",$2; }' | sed -e 's# ##g' | grep "$selectedimage") | |
if [[ -n "$imgmatches" ]]; then | |
foundmatching=1 | |
echo "${imgmatches}" | |
fi | |
# done | |
if [[ -z "$foundmatching" ]]; then | |
dockererror "Invalid image value. Please provide an image name and/or version or select a valid number from 1-${#imagenames[@]}. Partial names and wildcards are supported."; return 1; | |
fi | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment