github.com/nguyentm83/docker@v1.5.0/contrib/completion/bash/docker (about) 1 #!/bin/bash 2 # 3 # bash completion file for core docker commands 4 # 5 # This script provides completion of: 6 # - commands and their options 7 # - container ids and names 8 # - image repos and tags 9 # - filepaths 10 # 11 # To enable the completions either: 12 # - place this file in /etc/bash_completion.d 13 # or 14 # - copy this file to e.g. ~/.docker-completion.sh and add the line 15 # below to your .bashrc after bash completion features are loaded 16 # . ~/.docker-completion.sh 17 # 18 # Note: 19 # Currently, the completions will not work if the docker daemon is not 20 # bound to the default communication port/socket 21 # If the docker daemon is using a unix socket for communication your user 22 # must have access to the socket for the completions to function correctly 23 # 24 # Note for developers: 25 # Please arrange options sorted alphabetically by long name with the short 26 # options immediately following their corresponding long form. 27 # This order should be applied to lists, alternatives and code blocks. 28 29 __docker_q() { 30 docker 2>/dev/null "$@" 31 } 32 33 __docker_containers_all() { 34 local IFS=$'\n' 35 local containers=( $(__docker_q ps -aq --no-trunc) ) 36 if [ "$1" ]; then 37 containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") ) 38 fi 39 local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) 40 names=( "${names[@]#/}" ) # trim off the leading "/" from the container names 41 unset IFS 42 COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") ) 43 } 44 45 __docker_containers_running() { 46 __docker_containers_all '.State.Running' 47 } 48 49 __docker_containers_stopped() { 50 __docker_containers_all 'not .State.Running' 51 } 52 53 __docker_containers_pauseable() { 54 __docker_containers_all 'and .State.Running (not .State.Paused)' 55 } 56 57 __docker_containers_unpauseable() { 58 __docker_containers_all '.State.Paused' 59 } 60 61 __docker_image_repos() { 62 local repos="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')" 63 COMPREPLY=( $(compgen -W "$repos" -- "$cur") ) 64 } 65 66 __docker_image_repos_and_tags() { 67 local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1; print $1":"$2 }')" 68 COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") ) 69 __ltrim_colon_completions "$cur" 70 } 71 72 __docker_image_repos_and_tags_and_ids() { 73 local images="$(__docker_q images -a --no-trunc | awk 'NR>1 { print $3; if ($1 != "<none>") { print $1; print $1":"$2 } }')" 74 COMPREPLY=( $(compgen -W "$images" -- "$cur") ) 75 __ltrim_colon_completions "$cur" 76 } 77 78 __docker_containers_and_images() { 79 __docker_containers_all 80 local containers=( "${COMPREPLY[@]}" ) 81 __docker_image_repos_and_tags_and_ids 82 COMPREPLY+=( "${containers[@]}" ) 83 } 84 85 __docker_pos_first_nonflag() { 86 local argument_flags=$1 87 88 local counter=$cpos 89 while [ $counter -le $cword ]; do 90 if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then 91 (( counter++ )) 92 else 93 case "${words[$counter]}" in 94 -*) 95 ;; 96 *) 97 break 98 ;; 99 esac 100 fi 101 (( counter++ )) 102 done 103 104 echo $counter 105 } 106 107 # Transforms a multiline list of strings into a single line string 108 # with the words separated by "|". 109 # This is used to prepare arguments to __docker_pos_first_nonflag(). 110 __docker_to_alternatives() { 111 local parts=( $1 ) 112 local IFS='|' 113 echo "${parts[*]}" 114 } 115 116 # Transforms a multiline list of options into an extglob pattern 117 # suitable for use in case statements. 118 __docker_to_extglob() { 119 local extglob=$( __docker_to_alternatives "$1" ) 120 echo "@($extglob)" 121 } 122 123 __docker_resolve_hostname() { 124 command -v host >/dev/null 2>&1 || return 125 COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) 126 } 127 128 __docker_capabilities() { 129 # The list of capabilities is defined in types.go, ALL was added manually. 130 COMPREPLY=( $( compgen -W " 131 ALL 132 AUDIT_CONTROL 133 AUDIT_WRITE 134 BLOCK_SUSPEND 135 CHOWN 136 DAC_OVERRIDE 137 DAC_READ_SEARCH 138 FOWNER 139 FSETID 140 IPC_LOCK 141 IPC_OWNER 142 KILL 143 LEASE 144 LINUX_IMMUTABLE 145 MAC_ADMIN 146 MAC_OVERRIDE 147 MKNOD 148 NET_ADMIN 149 NET_BIND_SERVICE 150 NET_BROADCAST 151 NET_RAW 152 SETFCAP 153 SETGID 154 SETPCAP 155 SETUID 156 SYS_ADMIN 157 SYS_BOOT 158 SYS_CHROOT 159 SYSLOG 160 SYS_MODULE 161 SYS_NICE 162 SYS_PACCT 163 SYS_PTRACE 164 SYS_RAWIO 165 SYS_RESOURCE 166 SYS_TIME 167 SYS_TTY_CONFIG 168 WAKE_ALARM 169 " -- "$cur" ) ) 170 } 171 172 _docker_docker() { 173 local boolean_options=" 174 --api-enable-cors 175 --daemon -d 176 --debug -D 177 --help -h 178 --icc 179 --ip-forward 180 --ip-masq 181 --iptables 182 --ipv6 183 --selinux-enabled 184 --tls 185 --tlsverify 186 --version -v 187 " 188 189 case "$prev" in 190 --graph|-g) 191 _filedir -d 192 return 193 ;; 194 --log-level|-l) 195 COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) 196 return 197 ;; 198 --pidfile|-p|--tlscacert|--tlscert|--tlskey) 199 _filedir 200 return 201 ;; 202 --storage-driver|-s) 203 COMPREPLY=( $( compgen -W "aufs devicemapper btrfs overlay" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) 204 return 205 ;; 206 $main_options_with_args_glob ) 207 return 208 ;; 209 esac 210 211 case "$cur" in 212 -*) 213 COMPREPLY=( $( compgen -W "$boolean_options $main_options_with_args" -- "$cur" ) ) 214 ;; 215 *) 216 COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) 217 ;; 218 esac 219 } 220 221 _docker_attach() { 222 case "$cur" in 223 -*) 224 COMPREPLY=( $( compgen -W "--no-stdin --sig-proxy" -- "$cur" ) ) 225 ;; 226 *) 227 local counter="$(__docker_pos_first_nonflag)" 228 if [ $cword -eq $counter ]; then 229 __docker_containers_running 230 fi 231 ;; 232 esac 233 } 234 235 _docker_build() { 236 case "$prev" in 237 --tag|-t) 238 __docker_image_repos_and_tags 239 return 240 ;; 241 esac 242 243 case "$cur" in 244 -*) 245 COMPREPLY=( $( compgen -W "--force-rm --no-cache --quiet -q --rm --tag -t" -- "$cur" ) ) 246 ;; 247 *) 248 local counter="$(__docker_pos_first_nonflag '--tag|-t')" 249 if [ $cword -eq $counter ]; then 250 _filedir -d 251 fi 252 ;; 253 esac 254 } 255 256 _docker_commit() { 257 case "$prev" in 258 --author|-a|--message|-m|--run) 259 return 260 ;; 261 esac 262 263 case "$cur" in 264 -*) 265 COMPREPLY=( $( compgen -W "--author -a --message -m --run" -- "$cur" ) ) 266 ;; 267 *) 268 local counter=$(__docker_pos_first_nonflag '--author|-a|--message|-m|--run') 269 270 if [ $cword -eq $counter ]; then 271 __docker_containers_all 272 return 273 fi 274 (( counter++ )) 275 276 if [ $cword -eq $counter ]; then 277 __docker_image_repos_and_tags 278 return 279 fi 280 ;; 281 esac 282 } 283 284 _docker_cp() { 285 local counter=$(__docker_pos_first_nonflag) 286 if [ $cword -eq $counter ]; then 287 case "$cur" in 288 *:) 289 return 290 ;; 291 *) 292 __docker_containers_all 293 COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) 294 compopt -o nospace 295 return 296 ;; 297 esac 298 fi 299 (( counter++ )) 300 301 if [ $cword -eq $counter ]; then 302 _filedir 303 return 304 fi 305 } 306 307 _docker_create() { 308 _docker_run 309 } 310 311 _docker_diff() { 312 local counter=$(__docker_pos_first_nonflag) 313 if [ $cword -eq $counter ]; then 314 __docker_containers_all 315 fi 316 } 317 318 _docker_events() { 319 case "$prev" in 320 --since) 321 return 322 ;; 323 esac 324 325 case "$cur" in 326 -*) 327 COMPREPLY=( $( compgen -W "--since" -- "$cur" ) ) 328 ;; 329 esac 330 } 331 332 _docker_exec() { 333 case "$cur" in 334 -*) 335 COMPREPLY=( $( compgen -W "--detach -d --interactive -i -t --tty" -- "$cur" ) ) 336 ;; 337 *) 338 __docker_containers_running 339 ;; 340 esac 341 } 342 343 _docker_export() { 344 local counter=$(__docker_pos_first_nonflag) 345 if [ $cword -eq $counter ]; then 346 __docker_containers_all 347 fi 348 } 349 350 _docker_help() { 351 local counter=$(__docker_pos_first_nonflag) 352 if [ $cword -eq $counter ]; then 353 COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) 354 fi 355 } 356 357 _docker_history() { 358 case "$cur" in 359 -*) 360 COMPREPLY=( $( compgen -W "--no-trunc --quiet -q" -- "$cur" ) ) 361 ;; 362 *) 363 local counter=$(__docker_pos_first_nonflag) 364 if [ $cword -eq $counter ]; then 365 __docker_image_repos_and_tags_and_ids 366 fi 367 ;; 368 esac 369 } 370 371 _docker_images() { 372 case "$cur" in 373 -*) 374 COMPREPLY=( $( compgen -W "--all -a --no-trunc --quiet -q" -- "$cur" ) ) 375 ;; 376 *) 377 local counter=$(__docker_pos_first_nonflag) 378 if [ $cword -eq $counter ]; then 379 __docker_image_repos 380 fi 381 ;; 382 esac 383 } 384 385 _docker_import() { 386 local counter=$(__docker_pos_first_nonflag) 387 if [ $cword -eq $counter ]; then 388 return 389 fi 390 (( counter++ )) 391 392 if [ $cword -eq $counter ]; then 393 __docker_image_repos_and_tags 394 return 395 fi 396 } 397 398 _docker_info() { 399 return 400 } 401 402 _docker_inspect() { 403 case "$prev" in 404 --format|-f) 405 return 406 ;; 407 esac 408 409 case "$cur" in 410 -*) 411 COMPREPLY=( $( compgen -W "--format -f" -- "$cur" ) ) 412 ;; 413 *) 414 __docker_containers_and_images 415 ;; 416 esac 417 } 418 419 _docker_kill() { 420 __docker_containers_running 421 } 422 423 _docker_load() { 424 case "$prev" in 425 --input|-i) 426 _filedir 427 return 428 ;; 429 esac 430 431 case "$cur" in 432 -*) 433 COMPREPLY=( $( compgen -W "--input -i" -- "$cur" ) ) 434 ;; 435 esac 436 } 437 438 _docker_login() { 439 case "$prev" in 440 --email|-e|--password|-p|--username|-u) 441 return 442 ;; 443 esac 444 445 case "$cur" in 446 -*) 447 COMPREPLY=( $( compgen -W "--email -e --password -p --username -u" -- "$cur" ) ) 448 ;; 449 esac 450 } 451 452 _docker_logs() { 453 case "$cur" in 454 -*) 455 COMPREPLY=( $( compgen -W "--follow -f" -- "$cur" ) ) 456 ;; 457 *) 458 local counter=$(__docker_pos_first_nonflag) 459 if [ $cword -eq $counter ]; then 460 __docker_containers_all 461 fi 462 ;; 463 esac 464 } 465 466 _docker_pause() { 467 local counter=$(__docker_pos_first_nonflag) 468 if [ $cword -eq $counter ]; then 469 __docker_containers_pauseable 470 fi 471 } 472 473 _docker_port() { 474 local counter=$(__docker_pos_first_nonflag) 475 if [ $cword -eq $counter ]; then 476 __docker_containers_all 477 fi 478 } 479 480 _docker_ps() { 481 case "$prev" in 482 --before|--since) 483 __docker_containers_all 484 ;; 485 -n) 486 return 487 ;; 488 esac 489 490 case "$cur" in 491 -*) 492 COMPREPLY=( $( compgen -W "--all -a --before --latest -l --no-trunc -n --quiet -q --size -s --since" -- "$cur" ) ) 493 ;; 494 esac 495 } 496 497 _docker_pull() { 498 case "$prev" in 499 --tag|-t) 500 return 501 ;; 502 esac 503 504 case "$cur" in 505 -*) 506 COMPREPLY=( $( compgen -W "--tag -t" -- "$cur" ) ) 507 ;; 508 *) 509 local counter=$(__docker_pos_first_nonflag '--tag|-t') 510 if [ $cword -eq $counter ]; then 511 __docker_image_repos_and_tags 512 fi 513 ;; 514 esac 515 } 516 517 _docker_push() { 518 local counter=$(__docker_pos_first_nonflag) 519 if [ $cword -eq $counter ]; then 520 __docker_image_repos_and_tags 521 fi 522 } 523 524 _docker_restart() { 525 case "$prev" in 526 --time|-t) 527 return 528 ;; 529 esac 530 531 case "$cur" in 532 -*) 533 COMPREPLY=( $( compgen -W "--time -t" -- "$cur" ) ) 534 ;; 535 *) 536 __docker_containers_all 537 ;; 538 esac 539 } 540 541 _docker_rm() { 542 case "$cur" in 543 -*) 544 COMPREPLY=( $( compgen -W "--force -f --link -l --volumes -v" -- "$cur" ) ) 545 return 546 ;; 547 *) 548 for arg in "${COMP_WORDS[@]}"; do 549 case "$arg" in 550 --force|-f) 551 __docker_containers_all 552 return 553 ;; 554 esac 555 done 556 __docker_containers_stopped 557 return 558 ;; 559 esac 560 } 561 562 _docker_rmi() { 563 __docker_image_repos_and_tags_and_ids 564 } 565 566 _docker_run() { 567 local options_with_args=" 568 --add-host 569 --attach -a 570 --cap-add 571 --cap-drop 572 --cidfile 573 --cpuset 574 --cpu-shares -c 575 --device 576 --dns 577 --dns-search 578 --entrypoint 579 --env -e 580 --env-file 581 --expose 582 --hostname -h 583 --ipc 584 --link 585 --lxc-conf 586 --mac-address 587 --memory -m 588 --name 589 --net 590 --publish -p 591 --restart 592 --security-opt 593 --user -u 594 --volumes-from 595 --volume -v 596 --workdir -w 597 " 598 599 local all_options="$options_with_args 600 --interactive -i 601 --privileged 602 --publish-all -P 603 --tty -t 604 " 605 606 [ "$command" = "run" ] && all_options="$all_options 607 --detach -d 608 --rm 609 --sig-proxy 610 " 611 612 local options_with_args_glob=$(__docker_to_extglob "$options_with_args") 613 614 case "$prev" in 615 --add-host) 616 case "$cur" in 617 *:) 618 __docker_resolve_hostname 619 return 620 ;; 621 esac 622 ;; 623 --attach|-a) 624 COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) 625 return 626 ;; 627 --cap-add|--cap-drop) 628 __docker_capabilities 629 return 630 ;; 631 --cidfile|--env-file) 632 _filedir 633 return 634 ;; 635 --device|-d|--volume) 636 case "$cur" in 637 *:*) 638 # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine) 639 ;; 640 '') 641 COMPREPLY=( $( compgen -W '/' -- "$cur" ) ) 642 compopt -o nospace 643 ;; 644 /*) 645 _filedir 646 compopt -o nospace 647 ;; 648 esac 649 return 650 ;; 651 --env|-e) 652 COMPREPLY=( $( compgen -e -- "$cur" ) ) 653 compopt -o nospace 654 return 655 ;; 656 --ipc) 657 case "$cur" in 658 *:*) 659 cur="${cur#*:}" 660 __docker_containers_running 661 ;; 662 *) 663 COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) 664 if [ "$COMPREPLY" = "container:" ]; then 665 compopt -o nospace 666 fi 667 ;; 668 esac 669 return 670 ;; 671 --link) 672 case "$cur" in 673 *:*) 674 ;; 675 *) 676 __docker_containers_running 677 COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) 678 compopt -o nospace 679 ;; 680 esac 681 return 682 ;; 683 --net) 684 case "$cur" in 685 container:*) 686 local cur=${cur#*:} 687 __docker_containers_all 688 ;; 689 *) 690 COMPREPLY=( $( compgen -W "bridge none container: host" -- "$cur") ) 691 if [ "${COMPREPLY[*]}" = "container:" ] ; then 692 compopt -o nospace 693 fi 694 ;; 695 esac 696 return 697 ;; 698 --restart) 699 case "$cur" in 700 on-failure:*) 701 ;; 702 *) 703 COMPREPLY=( $( compgen -W "no on-failure on-failure: always" -- "$cur") ) 704 ;; 705 esac 706 return 707 ;; 708 --security-opt) 709 case "$cur" in 710 label:*:*) 711 ;; 712 label:*) 713 local cur=${cur##*:} 714 COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") ) 715 if [ "${COMPREPLY[*]}" != "disable" ] ; then 716 compopt -o nospace 717 fi 718 ;; 719 *) 720 COMPREPLY=( $( compgen -W "label apparmor" -S ":" -- "$cur") ) 721 compopt -o nospace 722 ;; 723 esac 724 return 725 ;; 726 --volumes-from) 727 __docker_containers_all 728 return 729 ;; 730 $options_with_args_glob ) 731 return 732 ;; 733 esac 734 735 case "$cur" in 736 -*) 737 COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) 738 ;; 739 *) 740 local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) 741 742 if [ $cword -eq $counter ]; then 743 __docker_image_repos_and_tags_and_ids 744 fi 745 ;; 746 esac 747 } 748 749 _docker_save() { 750 case "$prev" in 751 --output|-o) 752 _filedir 753 return 754 ;; 755 esac 756 757 case "$cur" in 758 -*) 759 COMPREPLY=( $( compgen -W "-o --output" -- "$cur" ) ) 760 ;; 761 *) 762 __docker_image_repos_and_tags_and_ids 763 ;; 764 esac 765 } 766 767 _docker_search() { 768 case "$prev" in 769 --stars|-s) 770 return 771 ;; 772 esac 773 774 case "$cur" in 775 -*) 776 COMPREPLY=( $( compgen -W "--automated --no-trunc --stars -s" -- "$cur" ) ) 777 ;; 778 esac 779 } 780 781 _docker_start() { 782 case "$cur" in 783 -*) 784 COMPREPLY=( $( compgen -W "--attach -a --interactive -i" -- "$cur" ) ) 785 ;; 786 *) 787 __docker_containers_stopped 788 ;; 789 esac 790 } 791 792 _docker_stats() { 793 __docker_containers_running 794 } 795 796 _docker_stop() { 797 case "$prev" in 798 --time|-t) 799 return 800 ;; 801 esac 802 803 case "$cur" in 804 -*) 805 COMPREPLY=( $( compgen -W "--time -t" -- "$cur" ) ) 806 ;; 807 *) 808 __docker_containers_running 809 ;; 810 esac 811 } 812 813 _docker_tag() { 814 case "$cur" in 815 -*) 816 COMPREPLY=( $( compgen -W "--force -f" -- "$cur" ) ) 817 ;; 818 *) 819 local counter=$(__docker_pos_first_nonflag) 820 821 if [ $cword -eq $counter ]; then 822 __docker_image_repos_and_tags 823 return 824 fi 825 (( counter++ )) 826 827 if [ $cword -eq $counter ]; then 828 __docker_image_repos_and_tags 829 return 830 fi 831 ;; 832 esac 833 } 834 835 _docker_unpause() { 836 local counter=$(__docker_pos_first_nonflag) 837 if [ $cword -eq $counter ]; then 838 __docker_containers_unpauseable 839 fi 840 } 841 842 _docker_top() { 843 local counter=$(__docker_pos_first_nonflag) 844 if [ $cword -eq $counter ]; then 845 __docker_containers_running 846 fi 847 } 848 849 _docker_version() { 850 return 851 } 852 853 _docker_wait() { 854 __docker_containers_all 855 } 856 857 _docker() { 858 local previous_extglob_setting=$(shopt -p extglob) 859 shopt -s extglob 860 861 local commands=( 862 attach 863 build 864 commit 865 cp 866 create 867 diff 868 events 869 exec 870 export 871 history 872 images 873 import 874 info 875 insert 876 inspect 877 kill 878 load 879 login 880 logs 881 pause 882 port 883 ps 884 pull 885 push 886 restart 887 rm 888 rmi 889 run 890 save 891 search 892 start 893 stats 894 stop 895 tag 896 top 897 unpause 898 version 899 wait 900 ) 901 902 local main_options_with_args=" 903 --bip 904 --bridge -b 905 --dns 906 --dns-search 907 --exec-driver -e 908 --fixed-cidr 909 --fixed-cidr-v6 910 --graph -g 911 --group -G 912 --host -H 913 --insecure-registry 914 --ip 915 --label 916 --log-level -l 917 --mtu 918 --pidfile -p 919 --registry-mirror 920 --storage-driver -s 921 --storage-opt 922 --tlscacert 923 --tlscert 924 --tlskey 925 " 926 927 local main_options_with_args_glob=$(__docker_to_extglob "$main_options_with_args") 928 929 COMPREPLY=() 930 local cur prev words cword 931 _get_comp_words_by_ref -n : cur prev words cword 932 933 local command='docker' cpos=0 934 local counter=1 935 while [ $counter -lt $cword ]; do 936 case "${words[$counter]}" in 937 $main_options_with_args_glob ) 938 (( counter++ )) 939 ;; 940 -*) 941 ;; 942 *) 943 command="${words[$counter]}" 944 cpos=$counter 945 (( cpos++ )) 946 break 947 ;; 948 esac 949 (( counter++ )) 950 done 951 952 local completions_func=_docker_${command} 953 declare -F $completions_func >/dev/null && $completions_func 954 955 eval "$previous_extglob_setting" 956 return 0 957 } 958 959 complete -F _docker docker