A simple zsh function for easily shelling into running Docker containers with tab completion.
Add this to your ~/.zshrc:
# Docker shell helper - shell into running containers
ds() {
local container="${1}"
local shell_cmd="${2:-}"
if [[ -z "$container" ]]; then
echo "Usage: ds <container> [shell]"
echo ""
echo "Examples:"
echo " ds my-container"
echo " ds nginx-123 /bin/sh"
return 1
fi
# Show which container we're entering
echo "\033[36mπ³ Entering container:\033[0m \033[1;34m$container\033[0m"
if [[ -n "$shell_cmd" ]]; then
echo "\033[90mβ Running: $shell_cmd\033[0m"
docker exec -it "$container" "$shell_cmd"
else
if docker exec "$container" command -v /bin/bash &>/dev/null; then
echo "\033[90mβ Running: /bin/bash\033[0m"
docker exec -it "$container" /bin/bash
else
echo "\033[90mβ Running: /bin/sh\033[0m"
docker exec -it "$container" /bin/sh
fi
fi
}
# Fuzzy completion for ds (inline, no popup)
_ds_complete() {
if [[ $CURRENT -eq 2 ]]; then
local containers=($(docker ps --filter "status=running" --format '{{.Names}}' 2>/dev/null))
local partial="${words[CURRENT]}"
local matches=()
# Fuzzy matching: find containers that contain the partial string (case insensitive)
for container in "${containers[@]}"; do
if [[ -z "$partial" ]] || [[ "${container:l}" == *"${partial:l}"* ]]; then
matches+=("$container")
fi
done
# If no substring matches, try simpler pattern matching
if [[ ${#matches[@]} -eq 0 && -n "$partial" ]]; then
for container in "${containers[@]}"; do
# Simple character sequence check: all chars from partial must appear in order
local container_lower="${container:l}"
local remaining="$container_lower"
local found=1
for (( i=1; i<=${#partial}; i++ )); do
local char="${partial[i]:l}"
if [[ "$remaining" == *"$char"* ]]; then
# Remove everything up to and including this character
remaining="${remaining#*$char}"
else
found=0
break
fi
done
if [[ $found -eq 1 ]]; then
matches+=("$container")
fi
done
fi
if [[ ${#matches[@]} -gt 0 ]]; then
_describe 'containers' matches
fi
fi
}
compdef _ds_complete dsThen reload your shell:
source ~/.zshrc# Shell into a container (auto-detects bash/sh)
ds my-container
# Use a specific shell
ds nginx-container /bin/zsh
# Fuzzy completion examples:
ds nginx<TAB> # Shows all containers containing "nginx"
ds dep<TAB> # Shows deployment-* containers
ds djg<TAB> # Shows docker-jenkins-group (character sequence: d-j-g)
ds api<TAB> # Shows containers containing "api"- π Simple zsh function - no external scripts
- π Fuzzy completion - substring and character sequence matching (case insensitive)
- β‘ Inline completion - works like standard tab completion but with fuzzy search
- π― No dependencies - pure zsh, no fzf or external tools required
- π Automatic shell detection (
/bin/bashβ/bin/shfallback) - βοΈ Override shell with second argument
- π¦ All-in-one - just add to your zshrc
- Zsh shell
- Docker installed and accessible
- Running Docker containers (for completion to work)
- Function: Creates a
dsfunction in your shell - Fuzzy Completion: Substring matching (case-insensitive) + character sequence matching (e.g., "djg" matches "docker-jenkins-group")
- Filtering: Only shows running containers (excludes restarting/stopped containers)
- Shell Detection: Tries
/bin/bashfirst, falls back to/bin/sh - Execution: Uses
docker exec -itfor interactive sessions
That's it! No files to manage, everything in your zshrc. π