diff options
Diffstat (limited to '')
-rw-r--r-- | completions/ssh | 563 | ||||
-rw-r--r-- | completions/ssh-add | 35 | ||||
-rw-r--r-- | completions/ssh-copy-id | 32 | ||||
-rw-r--r-- | completions/ssh-keygen | 123 | ||||
-rw-r--r-- | completions/sshfs | 23 | ||||
-rw-r--r-- | completions/sshmitm | 17 | ||||
-rw-r--r-- | completions/sshow | 26 |
7 files changed, 819 insertions, 0 deletions
diff --git a/completions/ssh b/completions/ssh new file mode 100644 index 0000000..907c039 --- /dev/null +++ b/completions/ssh @@ -0,0 +1,563 @@ +# ssh(1) completion -*- shell-script -*- + +_ssh_queries() +{ + COMPREPLY+=($(compgen -W \ + "cipher cipher-auth help mac kex key key-cert key-plain key-sig + protocol-version compression sig + ciphers macs kexalgorithms pubkeyacceptedkeytypes + hostkeyalgorithms hostbasedkeytypes hostbasedacceptedkeytypes" \ + -- "${cur,,}")) +} + +_ssh_query() +{ + ${1:-ssh} -Q $2 2>/dev/null +} + +_ssh_ciphers() +{ + local ciphers='$(_ssh_query "$1" cipher)' + [[ $ciphers ]] || ciphers="3des-cbc aes128-cbc aes192-cbc aes256-cbc + aes128-ctr aes192-ctr aes256-ctr arcfour128 arcfour256 arcfour + blowfish-cbc cast128-cbc" + COMPREPLY+=($(compgen -W "$ciphers" -- "$cur")) +} + +_ssh_macs() +{ + local macs='$(_ssh_query "$1" mac)' + [[ $macs ]] || macs="hmac-md5 hmac-sha1 umac-64@openssh.com hmac-ripemd160 + hmac-sha1-96 hmac-md5-96" + COMPREPLY+=($(compgen -W "$macs" -- "$cur")) +} + +_ssh_options() +{ + local opts=( + AddKeysToAgent AddressFamily BatchMode BindAddress CanonicalDomains + CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots + CanonicalizePermittedCNAMEs CASignatureAlgorithms CertificateFile + ChallengeResponseAuthentication CheckHostIP Ciphers ClearAllForwardings + Compression ConnectionAttempts ConnectTimeout ControlMaster ControlPath + ControlPersist DynamicForward EnableSSHKeysign EscapeChar + ExitOnForwardFailure FingerprintHash ForwardAgent ForwardX11 + ForwardX11Timeout ForwardX11Trusted GatewayPorts GlobalKnownHostsFile + GSSAPIAuthentication GSSAPIClientIdentity GSSAPIDelegateCredentials + GSSAPIKeyExchange GSSAPIRenewalForcesRekey GSSAPIServerIdentity + GSSAPITrustDns HashKnownHosts Host HostbasedAuthentication + HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName + IdentitiesOnly IdentityAgent IdentityFile IgnoreUnknown Include IPQoS + KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms + LocalCommand LocalForward LogLevel MACs + NoHostAuthenticationForLocalhost NumberOfPasswordPrompts + PasswordAuthentication PermitLocalCommand PKCS11Provider Port + PreferredAuthentications ProxyCommand ProxyJump ProxyUseFdpass + PubkeyAcceptedKeyTypes PubkeyAuthentication RekeyLimit RemoteCommand + RemoteForward RequestTTY RevokedHostKeys SendEnv ServerAliveCountMax + ServerAliveInterval SmartcardDevice StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking SyslogFacility TCPKeepAlive + Tunnel TunnelDevice UpdateHostKeys UsePrivilegedPort User + UserKnownHostsFile VerifyHostKeyDNS VisualHostKey XAuthLocation) + local protocols=$(_ssh_query "$1" protocol-version) + if [[ -z $protocols || $protocols == *1* ]]; then + opts+=(Cipher CompressionLevel Protocol RhostsRSAAuthentication + RSAAuthentication) + fi + + compopt -o nospace + local IFS=$' \t\n' reset=$(shopt -p nocasematch) + shopt -s nocasematch + local option + COMPREPLY=($(for option in "${opts[@]}"; do + [[ $option == "$cur"* ]] && printf '%s=\n' "$option" + done)) + $reset +} + +# Complete a ssh suboption (like ForwardAgent=y<tab>) +# Two parameters: the string to complete including the equal sign, and +# the ssh executable to invoke (optional). +# Not all suboptions are completed. +# Doesn't handle comma-separated lists. +_ssh_suboption() +{ + # Split into subopt and subval + local prev=${1%%=*} cur=${1#*=} + + case ${prev,,} in + batchmode | canonicaldomains | canonicalizefallbacklocal | \ + challengeresponseauthentication | checkhostip | \ + clearallforwardings | controlpersist | compression | enablesshkeysign | \ + exitonforwardfailure | forwardagent | forwardx11 | forwardx11trusted | \ + gatewayports | gssapiauthentication | gssapikeyexchange | \ + gssapidelegatecredentials | gssapirenewalforcesrekey | gssapitrustdns | \ + hashknownhosts | hostbasedauthentication | identitiesonly | \ + kbdinteractiveauthentication | kbdinteractivedevices | \ + nohostauthenticationforlocalhost | passwordauthentication | permitlocalcommand | \ + proxyusefdpass | pubkeyauthentication | rhostsrsaauthentication | \ + rsaauthentication | streamlocalbindunlink | \ + tcpkeepalive | useprivilegedport | visualhostkey) + COMPREPLY=($(compgen -W 'yes no' -- "$cur")) + ;; + addkeystoagent) + COMPREPLY=($(compgen -W 'yes ask confirm no' -- "$cur")) + ;; + addressfamily) + COMPREPLY=($(compgen -W 'any inet inet6' -- "$cur")) + ;; + bindaddress) + _ip_addresses + ;; + canonicalizehostname) + COMPREPLY=($(compgen -W 'yes no always' -- "$cur")) + ;; + identityfile) + _ssh_identityfile + ;; + *file | identityagent | include | controlpath | revokedhostkeys | xauthlocation) + _filedir + ;; + casignaturealgorithms) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" sig)' -- "$cur")) + ;; + cipher) + COMPREPLY=($(compgen -W 'blowfish des 3des' -- "$cur")) + ;; + ciphers) + _ssh_ciphers "$2" + ;; + controlmaster) + COMPREPLY=($(compgen -W 'yes ask auto autoask no' -- "$cur")) + ;; + compressionlevel) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + ;; + fingerprinthash) + COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur")) + ;; + ipqos) + COMPREPLY=($(compgen -W 'af1{1..4} af2{2..3} af3{1..3} af4{1..3} + cs{0..7} ef lowdelay throughput reliability' -- "$cur")) + ;; + hostbasedkeytypes | hostkeyalgorithms) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" key)' -- "$cur")) + ;; + kexalgorithms) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" kex)' -- "$cur")) + ;; + loglevel) + COMPREPLY=($(compgen -W 'QUIET FATAL ERROR INFO VERBOSE DEBUG{,1,2,3}' -- "$cur")) + ;; + macs) + _ssh_macs "$2" + ;; + pkcs11provider) + _filedir so + ;; + preferredauthentications) + COMPREPLY=($(compgen -W 'gssapi-with-mic host-based publickey + keyboard-interactive password' -- "$cur")) + ;; + protocol) + local protocols=($(_ssh_query "$2" protocol-version)) + [[ $protocols ]] || protocols=(1 2) + if ((${#protocols[@]} > 1)); then + COMPREPLY=($(compgen -W '${protocols[@]}' -- "$cur")) + fi + ;; + proxyjump) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + ;; + proxycommand | remotecommand | localcommand) + COMPREPLY=($(compgen -c -- "$cur")) + ;; + pubkeyacceptedkeytypes) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" key)' -- "$cur")) + ;; + requesttty) + COMPREPLY=($(compgen -W 'no yes force auto' -- "$cur")) + ;; + stricthostkeychecking) + COMPREPLY=($(compgen -W 'accept-new ask no off' -- "$cur")) + ;; + syslogfacility) + COMPREPLY=($(compgen -W 'DAEMON USER AUTH LOCAL{0..7}' -- "$cur")) + ;; + tunnel) + COMPREPLY=($(compgen -W 'yes no point-to-point ethernet' \ + -- "$cur")) + ;; + updatehostkeys | verifyhostkeydns) + COMPREPLY=($(compgen -W 'yes no ask' -- "$cur")) + ;; + esac + return 0 +} + +# Try to complete -o SubOptions= +# +# Returns 0 if the completion was handled or non-zero otherwise. +_ssh_suboption_check() +{ + # Get prev and cur words without splitting on = + local cureq=$(_get_cword :=) preveq=$(_get_pword :=) + if [[ $cureq == *=* && $preveq == -*o ]]; then + _ssh_suboption $cureq "$1" + return $? + fi + return 1 +} + +# Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument +_ssh_configfile() +{ + set -- "${words[@]}" + while (($# > 0)); do + if [[ $1 == -F* ]]; then + if ((${#1} > 2)); then + configfile="$(dequote "${1:2}")" + else + shift + [[ ${1-} ]] && configfile="$(dequote "$1")" + fi + break + fi + shift + done +} + +# With $1 set, look for public key files, else private +# shellcheck disable=SC2120 +_ssh_identityfile() +{ + [[ -z $cur && -d ~/.ssh ]] && cur=~/.ssh/id + _filedir + if ((${#COMPREPLY[@]} > 0)); then + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' \ + -X "${1:+!}*.pub" -- "$cur")) + fi +} + +_ssh() +{ + local cur prev words cword + _init_completion -n : || return + + local configfile + _ssh_configfile + + _ssh_suboption_check "$1" && return + + local ipvx + + case $prev in + -*b) + _ip_addresses + return + ;; + -*c) + _ssh_ciphers "$1" + return + ;; + -*[DeLpRW]) + return + ;; + -*[EFS]) + _filedir + return + ;; + -*i) + _ssh_identityfile + return + ;; + -*I) + _filedir so + return + ;; + -*J) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + return + ;; + -*l) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -*m) + _ssh_macs "$1" + return + ;; + -*O) + COMPREPLY=($(compgen -W 'check forward cancel exit stop' -- "$cur")) + return + ;; + -*o) + _ssh_options "$1" + return + ;; + -*Q) + _ssh_queries "$1" + return + ;; + -*w) + _available_interfaces + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + if [[ $cur == -F* ]]; then + cur=${cur#-F} + _filedir + # Prefix completions with '-F' + COMPREPLY=("${COMPREPLY[@]/#/-F}") + cur=-F$cur # Restore cur + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real ${ipvx-} -a ${configfile:+-F "$configfile"} -- "$cur" + + local args + _count_args + if ((args > 1)); then + compopt -o filenames + COMPREPLY+=($(compgen -c -- "$cur")) + fi + fi +} && + shopt -u hostcomplete && complete -F _ssh ssh slogin autossh sidedoor + +# sftp(1) completion +# +_sftp() +{ + local cur prev words cword + _init_completion || return + + local configfile + _ssh_configfile + + _ssh_suboption_check && return + + local ipvx + + case $prev in + -*[BDlPRs]) + return + ;; + -*[bF]) + _filedir + return + ;; + -*i) + _ssh_identityfile + return + ;; + -*c) + _ssh_ciphers + return + ;; + -*J) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + return + ;; + -*o) + _ssh_options + return + ;; + -*S) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + if [[ $cur == -F* ]]; then + cur=${cur#-F} + _filedir + # Prefix completions with '-F' + COMPREPLY=("${COMPREPLY[@]/#/-F}") + cur=-F$cur # Restore cur + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real ${ipvx-} -a ${configfile:+-F "$configfile"} -- "$cur" + fi +} && + shopt -u hostcomplete && complete -F _sftp sftp + +# things we want to backslash escape in scp paths +# shellcheck disable=SC2089 +_scp_path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' + +# Complete remote files with ssh. If the first arg is -d, complete on dirs +# only. Returns paths escaped with three backslashes. +# shellcheck disable=SC2120 +_scp_remote_files() +{ + local IFS=$'\n' + + # remove backslash escape from the first colon + cur=${cur/\\:/:} + + local userhost=${cur%%?(\\):*} + local path=${cur#*:} + + # unescape (3 backslashes to 1 for chars we escaped) + # shellcheck disable=SC2090 + path=$(command sed -e 's/\\\\\\\('$_scp_path_esc'\)/\\\1/g' <<<"$path") + + # default to home dir of specified user on remote host + if [[ -z $path ]]; then + path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null) + fi + + local files + if [[ $1 == -d ]]; then + # escape problematic characters; remove non-dirs + # shellcheck disable=SC2090 + files=$(ssh -o 'Batchmode yes' $userhost \ + command ls -aF1dL "$path*" 2>/dev/null | + command sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e '/[^\/]$/d') + else + # escape problematic characters; remove executables, aliases, pipes + # and sockets; add space at end of file names + # shellcheck disable=SC2090 + files=$(ssh -o 'Batchmode yes' $userhost \ + command ls -aF1dL "$path*" 2>/dev/null | + command sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e 's/[*@|=]$//g' \ + -e 's/[^\/]$/& /g') + fi + COMPREPLY+=($files) +} + +# This approach is used instead of _filedir to get a space appended +# after local file/dir completions, and -o nospace retained for others. +# If first arg is -d, complete on directory names only. The next arg is +# an optional prefix to add to returned completions. +_scp_local_files() +{ + local IFS=$'\n' + + local dirsonly=false + if [[ ${1-} == -d ]]; then + dirsonly=true + shift + fi + + if $dirsonly; then + COMPREPLY+=($(command ls -aF1dL $cur* 2>/dev/null | + command sed -e "s/$_scp_path_esc/\\\\&/g" -e '/[^\/]$/d' -e "s/^/${1-}/")) + else + COMPREPLY+=($(command ls -aF1dL $cur* 2>/dev/null | + command sed -e "s/$_scp_path_esc/\\\\&/g" -e 's/[*@|=]$//g' \ + -e 's/[^\/]$/& /g' -e "s/^/${1-}/")) + fi +} + +# scp(1) completion +# +_scp() +{ + local cur prev words cword + _init_completion -n : || return + + local configfile + _ssh_configfile + + _ssh_suboption_check && { + COMPREPLY=("${COMPREPLY[@]/%/ }") + return + } + + local ipvx + + case $prev in + -*c) + _ssh_ciphers + COMPREPLY=("${COMPREPLY[@]/%/ }") + return + ;; + -*F) + _filedir + compopt +o nospace + return + ;; + -*i) + _ssh_identityfile + compopt +o nospace + return + ;; + -*J) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + return + ;; + -*[lP]) + return + ;; + -*o) + _ssh_options + return + ;; + -*S) + compopt +o nospace -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + _expand || return + + case $cur in + !(*:*)/* | [.~]*) ;; # looks like a path + *:*) + _scp_remote_files + return + ;; + esac + + local prefix + + if [[ $cur == -F* ]]; then + cur=${cur#-F} + prefix=-F + else + case $cur in + -*) + COMPREPLY=($(compgen -W '$(_parse_usage "${words[0]}")' \ + -- "$cur")) + COMPREPLY=("${COMPREPLY[@]/%/ }") + return + ;; + */* | [.~]*) + # not a known host, pass through + ;; + *) + _known_hosts_real ${ipvx-} -c -a \ + ${configfile:+-F "$configfile"} -- "$cur" + ;; + esac + fi + + _scp_local_files "${prefix-}" +} && + complete -F _scp -o nospace scp + +# ex: filetype=sh diff --git a/completions/ssh-add b/completions/ssh-add new file mode 100644 index 0000000..d8f7492 --- /dev/null +++ b/completions/ssh-add @@ -0,0 +1,35 @@ +# ssh-add(1) completion -*- shell-script -*- + +_ssh_add() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*E) + COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur")) + return + ;; + -*t) + return + ;; + -*T) + _filedir + return + ;; + -*[se]) + _filedir so + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" "-\?")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _ssh_add ssh-add + +# ex: filetype=sh diff --git a/completions/ssh-copy-id b/completions/ssh-copy-id new file mode 100644 index 0000000..f628194 --- /dev/null +++ b/completions/ssh-copy-id @@ -0,0 +1,32 @@ +# ssh-copy-id(1) completion -*- shell-script -*- + +_ssh_copy_id() +{ + local cur prev words cword + _init_completion || return + + _xfunc ssh _ssh_suboption_check "$1" && return + + case $prev in + -i) + _xfunc ssh _ssh_identityfile pub + return + ;; + -p) + return + ;; + -o) + _xfunc ssh _ssh_options + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _known_hosts_real -a -- "$cur" + fi +} && + complete -F _ssh_copy_id ssh-copy-id + +# ex: filetype=sh diff --git a/completions/ssh-keygen b/completions/ssh-keygen new file mode 100644 index 0000000..0e629a5 --- /dev/null +++ b/completions/ssh-keygen @@ -0,0 +1,123 @@ +# ssh-keygen(1) completion -*- shell-script -*- + +_ssh_keygen() +{ + local cur prev words cword + _init_completion -n := || return + + case $prev in + -*[aCIJjMNPSVWz]) + return + ;; + -*b) + local -a sizes + case "${words[*]}" in + *" -t dsa"?( *)) + sizes=(1024) + ;; + *" -t ecdsa"?( *)) + sizes=(256 384 521) + ;; + *" -t rsa"?( *)) + sizes=(1024 2048 3072 4096) + ;; + esac + COMPREPLY=($(compgen -W '${sizes[@]}' -- "$cur")) + return + ;; + -*E) + COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur")) + return + ;; + -*[FR]) + # TODO: trim this down to actual entries in known hosts files + _known_hosts_real -- "$cur" + return + ;; + -*[Dw]) + _filedir so + return + ;; + -*[fGKsT]) + _filedir + return + ;; + -*m) + COMPREPLY=($(compgen -W 'PEM PKCS8 RFC4716' -- "$cur")) + return + ;; + -*n) + [[ ${words[*]} != *\ -*Y\ * ]] || return + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + if [[ ${words[*]} == *\ -*h\ * ]]; then + _known_hosts_real -- "${cur##*,}" + else + COMPREPLY=($(compgen -u -- "${cur##*,}")) + fi + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + -*O) + if [[ $cur != *=* ]]; then + COMPREPLY=($(compgen -W ' + clear critical: extension: force-command= + no-agent-forwarding no-port-forwarding no-pty no-user-rc + no-x11-forwarding permit-agent-forwarding + permit-port-forwarding permit-pty permit-user-rc + permit-X11-forwarding no-touch-required source-address= + + lines= start-line= checkpoint= memory= start= generator= + + application challenge= device resident user + write-attestation-path + ' -- "$cur")) + [[ ${COMPREPLY-} == *[:=] ]] && compopt -o nospace + __ltrim_colon_completions "$cur" + else + case $cur in + force-command=*) + compopt -o filenames + COMPREPLY=($(compgen -c -- "${cur#*=}")) + ;; + checkpoint=* | challenge=*) + cur=${cur#*=} + _filedir + ;; + esac + fi + return + ;; + -*r) + [[ ${words[*]} != *\ -*Y\ * ]] || _filedir + return + ;; + -*t) + local protocols=$(_xfunc ssh _ssh_query "$1" protocol-version) + local types='dsa ecdsa ecdsa-sk ed25519 ed25519-sk rsa' + if [[ $protocols == *1* ]]; then + types+=' rsa1' + fi + COMPREPLY=($(compgen -W "$types" -- "$cur")) + return + ;; + -*Y) + COMPREPLY=($(compgen -W 'find-principals check-novalidate sign + verify' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_usage "$1" "-?") + [[ -z $opts ]] && opts=$(_parse_help "$1" "-?") # OpenSSH < 7 + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + fi + + if [[ ${words[*]} == *\ -*s\ * ]]; then + _filedir pub + fi +} && + complete -F _ssh_keygen ssh-keygen + +# ex: filetype=sh diff --git a/completions/sshfs b/completions/sshfs new file mode 100644 index 0000000..223d029 --- /dev/null +++ b/completions/sshfs @@ -0,0 +1,23 @@ +# sshfs(1) completion -*- shell-script -*- + +_sshfs() +{ + local cur prev words cword + _init_completion -n : || return + + _expand || return + + if [[ $cur == *:* ]]; then + _xfunc ssh _scp_remote_files -d + # unlike scp and rsync, sshfs works with 1 backslash instead of 3 + COMPREPLY=("${COMPREPLY[@]//\\\\\\/\\}") + return + fi + + [[ $cur == @(*/|[.~])* ]] || _known_hosts_real -c -a -- "$cur" + + _xfunc ssh _scp_local_files -d +} && + complete -F _sshfs -o nospace sshfs + +# ex: filetype=sh diff --git a/completions/sshmitm b/completions/sshmitm new file mode 100644 index 0000000..ee893e5 --- /dev/null +++ b/completions/sshmitm @@ -0,0 +1,17 @@ +# sshmitm completion -*- shell-script -*- + +_sshmitm() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi + +} && + complete -F _sshmitm sshmitm + +# ex: filetype=sh diff --git a/completions/sshow b/completions/sshow new file mode 100644 index 0000000..917444e --- /dev/null +++ b/completions/sshow @@ -0,0 +1,26 @@ +# sshow completion -*- shell-script -*- + +_sshow() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*i) + _available_interfaces -a + return + ;; + -*p) + _filedir pcap + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _sshow sshow + +# ex: filetype=sh |