# ip(8) completion -*- shell-script -*- _iproute2_etc() { COMPREPLY+=($(compgen -W \ "$(awk '!/#/ { print $2 }' /etc/iproute2/$1 2>/dev/null)" \ -- "$cur")) } _ip() { local cur prev words cword _init_completion || return case $prev in -V | -Version | -rc | -rcvbuf) return ;; -f | -family) COMPREPLY=($(compgen -W 'inet inet6 ipx dnet link' -- "$cur")) return ;; -b | -batch) _filedir return ;; -force) COMPREPLY=($(compgen -W '-batch' -- "$cur")) return ;; esac local subcword cmd subcmd="" for ((subcword = 1; subcword < ${#words[@]} - 1; subcword++)); do [[ ${words[subcword]} == -b?(atch) ]] && return [[ -v cmd ]] && subcmd=${words[subcword]} && break [[ ${words[subcword]} != -* && \ ${words[subcword - 1]} != -@(f?(amily)|rc?(vbuf)) ]] && cmd=${words[subcword]} done if [[ ! -v cmd ]]; then case $cur in -*) local c="-Version -statistics -details -resolve -family -oneline -timestamp -batch -rcvbuf" ((cword == 1)) && c+=" -force" COMPREPLY=($(compgen -W "$c" -- "$cur")) ;; *) COMPREPLY=($(compgen -W "help $($1 help 2>&1 | command sed -e \ '/OBJECT := /,/}/!d' -e \ 's/.*{//' -e \ 's/}.*//' -e \ 's/|//g')" -- "$cur")) ;; esac return fi [[ $subcmd == help ]] && return case $cmd in l | link) case $subcmd in add) # TODO ;; delete) case $((cword - subcword)) in 1) _available_interfaces ;; 2) COMPREPLY=($(compgen -W 'type' -- "$cur")) ;; 3) [[ $prev == type ]] && COMPREPLY=($(compgen -W 'vlan veth vcan dummy ifb macvlan can' -- "$cur")) ;; esac ;; set) if ((cword - subcword == 1)); then _available_interfaces else case $prev in arp | dynamic | multicast | allmulticast | promisc | \ trailers) COMPREPLY=($(compgen -W 'on off' -- "$cur")) ;; txqueuelen | name | address | broadcast | mtu | netns | alias) ;; *) local c="arp dynamic multicast allmulticast promisc trailers txqueuelen name address broadcast mtu netns alias" [[ $prev != @(up|down) ]] && c+=" up down" COMPREPLY=($(compgen -W "$c" -- "$cur")) ;; esac fi ;; show) if ((cword == subcword + 1)); then _available_interfaces COMPREPLY+=($(compgen -W 'dev group up' -- "$cur")) elif [[ $prev == dev ]]; then _available_interfaces elif [[ $prev == group ]]; then _iproute2_etc group fi ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add delete set show' \ -- "$cur")) ;; esac ;; a | addr | address) case $subcmd in add | change | replace) if [[ $prev == dev ]]; then _available_interfaces elif [[ $prev == scope ]]; then _iproute2_etc rt_scopes else : # TODO fi ;; del) if [[ $prev == dev ]]; then _available_interfaces elif [[ $prev == scope ]]; then _iproute2_etc rt_scopes else : # TODO fi ;; show | flush) if ((cword == subcword + 1)); then _available_interfaces COMPREPLY+=($(compgen -W 'dev scope to label dynamic permanent tentative deprecated dadfailed temporary primary secondary up' -- "$cur")) elif [[ $prev == dev ]]; then _available_interfaces elif [[ $prev == scope ]]; then _iproute2_etc rt_scopes fi ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add change replace del show flush' -- "$cur")) ;; esac ;; addrlabel) case $subcmd in list | add | del | flush) if [[ $prev == dev ]]; then _available_interfaces else : # TODO fi ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help list add del flush' \ -- "$cur")) ;; esac ;; r | route) case $subcmd in list | flush) if [[ $prev == proto ]]; then _iproute2_etc rt_protos else : # TODO fi ;; get) # TODO ;; a | add | d | del | change | append | r | replace | monitor) if [[ $prev == via ]]; then COMPREPLY=($(compgen -W "$($1 r | command sed -ne \ 's/.*via \([0-9.]*\).*/\1/p')" -- "$cur")) elif [[ $prev == "$subcmd" ]]; then COMPREPLY=($(compgen -W "table default \ $($1 r | cut -d ' ' -f 1)" -- "$cur")) elif [[ $prev == dev ]]; then _available_interfaces -a elif [[ $prev == table ]]; then COMPREPLY=($(compgen -W 'local main default' -- "$cur")) else COMPREPLY=($(compgen -W 'via dev weight' -- "$cur")) fi ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help list flush get add del change append replace monitor' -- "$cur")) ;; esac ;; rule) case $subcmd in add | del | list | lst) case $prev in from | to | tos | dsfield | fwmark | uidrange | ipproto | sport | \ dport | priority | protocol | suppress_prefixlength | \ suppress_ifgroup | realms | nat | goto) ;; iif | oif) _available_interfaces -a ;; table | lookup) COMPREPLY=($(compgen -W 'local main default' -- "$cur")) ;; *) COMPREPLY=($(compgen -W 'from to tos dsfield fwmark uidrange ipproto sport dport priority table lookup protocol suppress_prefixlength suppress_ifgroup realms nat goto iif oif not' -- "$cur")) ;; esac ;; flush | save) if [[ $prev == protocol ]]; then : else COMPREPLY=($(compgen -W 'protocol' -- "$cur")) fi ;; restore | show) ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add del list flush save restore show' -- "$cur")) ;; esac ;; neigh) case $subcmd in add | del | change | replace) # TODO ;; show | flush) # TODO ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add del change replace show flush' -- "$cur")) ;; esac ;; ntable) case $subcmd in change) # TODO ;; show) # TODO ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help change show' \ -- "$cur")) ;; esac ;; tunnel) case $subcmd in show) ;; add | change | del | prl | 6rd) # TODO ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add change del show prl 6rd' -- "$cur")) ;; esac ;; maddr) case $subcmd in add | del) # TODO ;; show) if [[ $cword -eq $subcword+1 || $prev == dev ]]; then _available_interfaces [[ $prev != dev ]] && COMPREPLY=($(compgen -W '${COMPREPLY[@]} dev' \ -- "$cur")) fi ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add del show' \ -- "$cur")) ;; esac ;; mroute) case $subcmd in show) # TODO ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help show' -- "$cur")) ;; esac ;; monitor) case $subcmd in all) ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help all' -- "$cur")) ;; esac ;; netns) case $subcmd in list | monitor) ;; add | identify | list-id) # TODO ;; delete | exec | pids | set) [[ $prev == "$subcmd" ]] && COMPREPLY=($(compgen -W "$($1 netns list)" -- "$cur")) ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'help add delete exec identify list list-id monitor pids set' -- "$cur")) ;; esac ;; xfrm) case $subcmd in state | policy | monitor) # TODO ;; *) ((cword == subcword)) && COMPREPLY=($(compgen -W 'state policy monitor' \ -- "$cur")) ;; esac ;; esac } && complete -F _ip ip # ex: filetype=sh