Ticket #44558: ssh

File ssh, 11.5 KB (added by Daniel.Lipofsky@…, 10 years ago)

/opt/local/share/bash-completion/completions/ssh

Line 
1# ssh(1) completion                                        -*- shell-script -*-
2
3_ssh_ciphers()
4{
5    COMPREPLY+=( $( compgen -W '3des-cbc aes128-cbc aes192-cbc aes256-cbc
6        aes128-ctr aes192-ctr aes256-ctr arcfour128 arcfour256 arcfour
7        blowfish-cbc cast128-cbc' -- "$cur" ) )
8}
9
10_ssh_macs()
11{
12    COMPREPLY+=( $( compgen -W 'hmac-md5 hmac-sha1 umac-64@openssh.com
13        hmac-ripemd160 hmac-sha1-96 hmac-md5-96' -- "$cur" ) )
14}
15
16_ssh_options()
17{
18    compopt -o nospace
19    COMPREPLY=( $( compgen -S = -W 'AddressFamily BatchMode BindAddress
20        ChallengeResponseAuthentication CheckHostIP Cipher Ciphers
21        ClearAllForwardings Compression CompressionLevel ConnectionAttempts
22        ConnectTimeout ControlMaster ControlPath ControlPersist DynamicForward
23        EnableSSHKeysign EscapeChar ExitOnForwardFailure ForwardAgent
24        ForwardX11 ForwardX11Timeout ForwardX11Trusted GatewayPorts
25        GlobalKnownHostsFile GSSAPIAuthentication GSSAPIClientIdentity
26        GSSAPIDelegateCredentials GSSAPIKeyExchange GSSAPIRenewalForcesRekey
27        GSSAPIServerIdentity GSSAPITrustDns HashKnownHosts Host
28        HostbasedAuthentication HostKeyAlgorithms HostKeyAlias HostName
29        IdentityFile IdentitiesOnly IPQoS KbdInteractiveDevices KexAlgorithms
30        LocalCommand LocalForward LogLevel MACs
31        NoHostAuthenticationForLocalhost NumberOfPasswordPrompts
32        PasswordAuthentication PermitLocalCommand PKCS11Provider Port
33        PreferredAuthentications Protocol ProxyCommand PubkeyAuthentication
34        RekeyLimit RemoteForward RequestTTY RhostsRSAAuthentication
35        RSAAuthentication SendEnv ServerAliveCountMax ServerAliveInterval
36        SmartcardDevice StrictHostKeyChecking TCPKeepAlive Tunnel TunnelDevice
37        UsePrivilegedPort User UserKnownHostsFile VerifyHostKeyDNS
38        VisualHostKey XAuthLocation' -- "$cur" ) )
39}
40
41# Complete a ssh suboption (like ForwardAgent=y<tab>)
42# Only one parameter: the string to complete including the equal sign.
43# Not all suboptions are completed.
44# Doesn't handle comma-separated lists.
45_ssh_suboption()
46{
47    # Split into subopt and subval
48    local prev=${1%%=*} cur=${1#*=}
49
50    case $prev in
51        BatchMode|ChallengeResponseAuthentication|CheckHostIP|\
52        ClearAllForwardings|ControlPersist|Compression|EnableSSHKeysign|\
53        ExitOnForwardFailure|ForwardAgent|ForwardX11|ForwardX11Trusted|\
54        GatewayPorts|GSSAPIAuthentication|GSSAPIKeyExchange|\
55        GSSAPIDelegateCredentials|GSSAPIRenewalForcesRekey|GSSAPITrustDns|\
56        HashKnownHosts|HostbasedAuthentication|IdentitiesOnly|\
57        KbdInteractiveAuthentication|KbdInteractiveDevices|\
58        NoHostAuthenticationForLocalhost|PasswordAuthentication|\
59        PubkeyAuthentication|RhostsRSAAuthentication|RSAAuthentication|\
60        StrictHostKeyChecking|TCPKeepAlive|UsePrivilegedPort|\
61        VerifyHostKeyDNS|VisualHostKey)
62            COMPREPLY=( $( compgen -W 'yes no' -- "$cur" ) )
63            ;;
64        AddressFamily)
65            COMPREPLY=( $( compgen -W 'any inet inet6' -- "$cur" ) )
66            ;;
67        BindAddress)
68            _ip_addresses
69            ;;
70        Cipher)
71            COMPREPLY=( $( compgen -W 'blowfish des 3des' -- "$cur" ) )
72            ;;
73        IPQoS)
74            COMPREPLY=( $( compgen -W 'af1{1..4} af2{2..3} af3{1..3} af4{1..3}
75                cs{0..7} ef lowdelay throughput reliability' -- "$cur" ) )
76            ;;
77        Protocol)
78            COMPREPLY=( $( compgen -W '1 2 1,2 2,1' -- "$cur" ) )
79            ;;
80        RequestTTY)
81            COMPREPLY=( $( compgen -W 'no yes force auto' -- "$cur" ) )
82            ;;
83        Tunnel)
84            COMPREPLY=( $( compgen -W 'yes no point-to-point ethernet' \
85                    -- "$cur" ) )
86            ;;
87        PreferredAuthentications)
88            COMPREPLY=( $( compgen -W 'gssapi-with-mic host-based publickey
89                keyboard-interactive password' -- "$cur" ) )
90            ;;
91        MACs)
92            _ssh_macs
93            ;;
94        Ciphers)
95            _ssh_ciphers
96            ;;
97    esac
98    return 0
99}
100
101# Try to complete -o SubOptions=
102#
103# Returns 0 if the completion was handled or non-zero otherwise.
104_ssh_suboption_check()
105{
106    # Get prev and cur words without splitting on =
107    local cureq=`_get_cword :=` preveq=`_get_pword :=`
108    if [[ $cureq == *=* && $preveq == -o ]]; then
109        _ssh_suboption $cureq
110        return $?
111    fi
112    return 1
113}
114
115_ssh()
116{
117    local cur prev words cword
118    _init_completion -n : || return
119
120    local configfile
121    local -a config
122
123    _ssh_suboption_check && return 0
124
125    case $prev in
126        -F|-i|-S)
127            _filedir
128            return 0
129            ;;
130        -c)
131            _ssh_ciphers
132            return 0
133            ;;
134        -m)
135            _ssh_macs
136            return 0
137            ;;
138        -l)
139            COMPREPLY=( $( compgen -u -- "$cur" ) )
140            return 0
141            ;;
142        -O)
143            COMPREPLY=( $( compgen -W 'check forward exit stop' -- "$cur" ) )
144            return 0
145            ;;
146        -o)
147            _ssh_options
148            return 0
149            ;;
150        -w)
151            _available_interfaces
152            return 0
153            ;;
154        -b)
155            _ip_addresses
156            return 0
157            ;;
158        -D|-e|-I|-L|-p|-R|-W)
159            return 0
160            ;;
161    esac
162
163    if [[ "$cur" == -F* ]]; then
164        cur=${cur#-F}
165        _filedir
166        # Prefix completions with '-F'
167        COMPREPLY=( "${COMPREPLY[@]/#/-F}" )
168        cur=-F$cur  # Restore cur
169    elif [[ "$cur" == -* ]]; then
170        COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) )
171    else
172        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
173        set -- "${words[@]}"
174        while [[ $# -gt 0 ]]; do
175            if [[ $1 == -F* ]]; then
176                if [[ ${#1} -gt 2 ]]; then
177                    configfile="$(dequote "${1:2}")"
178                else
179                    shift
180                    [[ $1 ]] && configfile="$(dequote "$1")"
181                fi
182                break
183            fi
184            shift
185        done
186        _known_hosts_real -a -F "$configfile" "$cur"
187        if [[ $cword -ne 1 ]]; then
188            compopt -o filenames
189            COMPREPLY+=( $( compgen -c -- "$cur" ) )
190        fi
191    fi
192
193    return 0
194} &&
195shopt -u hostcomplete && complete -F _ssh ssh slogin autossh
196
197# sftp(1) completion
198#
199_sftp()
200{
201    local cur prev words cword
202    _init_completion || return
203
204    local configfile
205
206    _ssh_suboption_check && return 0
207
208    case $prev in
209        -b|-F|-i)
210            _filedir
211            return 0
212            ;;
213        -o)
214            _ssh_options
215            return 0
216            ;;
217        -c)
218            _ssh_ciphers
219            return 0
220            ;;
221        -B|-D|-P|-R|-S|-s)
222            return 0
223            ;;
224    esac
225
226    if [[ "$cur" == -F* ]]; then
227        cur=${cur#-F}
228        _filedir
229        # Prefix completions with '-F'
230        COMPREPLY=( "${COMPREPLY[@]/#/-F}" )
231        cur=-F$cur  # Restore cur
232    elif [[ "$cur" == -* ]]; then
233        COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) )
234    else
235        # Search COMP_WORDS for '-F configfile' argument
236        set -- "${words[@]}"
237        while [[ $# -gt 0 ]]; do
238            if [[ $1 == -F* ]]; then
239                if [[ ${#1} -gt 2 ]]; then
240                    configfile="$(dequote "${1:2}")"
241                else
242                    shift
243                    [[ $1 ]] && configfile="$(dequote "$1")"
244                fi
245                break
246            fi
247            shift
248        done
249        _known_hosts_real -a -F "$configfile" "$cur"
250    fi
251
252    return 0
253} &&
254shopt -u hostcomplete && complete -F _sftp sftp
255
256# things we want to backslash escape in scp paths
257_scp_path_esc='[][(){}<>",:;^&!$=?`|\\'"'"'[:space:]]'
258
259# Complete remote files with ssh.  If the first arg is -d, complete on dirs
260# only.  Returns paths escaped with three backslashes.
261_scp_remote_files()
262{
263    local IFS=$'\n'
264
265    # remove backslash escape from the first colon
266    cur=${cur/\\:/:}
267
268    local userhost=${cur%%?(\\):*}
269    local path=${cur#*:}
270
271    # unescape (3 backslashes to 1 for chars we escaped)
272    path=$( sed -e 's/\\\\\\\('$_scp_path_esc'\)/\\\1/g' <<<"$path" )
273
274    # default to home dir of specified user on remote host
275    if [[ -z $path ]]; then
276        path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
277    fi
278
279    local files
280    if [[ $1 == -d ]]; then
281        # escape problematic characters; remove non-dirs
282        files=$( ssh -o 'Batchmode yes' $userhost \
283            command ls -aF1dL "$path*" 2>/dev/null | \
284            sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e '/[^\/]$/d' )
285    else
286        # escape problematic characters; remove executables, aliases, pipes
287        # and sockets; add space at end of file names
288        files=$( ssh -o 'Batchmode yes' $userhost \
289            command ls -aF1dL "$path*" 2>/dev/null | \
290            sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e 's/[*@|=]$//g' \
291            -e 's/[^\/]$/& /g' )
292    fi
293    COMPREPLY+=( $files )
294}
295
296# This approach is used instead of _filedir to get a space appended
297# after local file/dir completions, and -o nospace retained for others.
298# If first arg is -d, complete on directory names only.  The next arg is
299# an optional prefix to add to returned completions.
300_scp_local_files()
301{
302    local IFS=$'\n'
303
304    local dirsonly=false
305    if [[ $1 == -d ]]; then
306        dirsonly=true
307        shift
308    fi
309
310    if $dirsonly ; then
311        COMPREPLY+=( $( command ls -aF1dL $cur* 2>/dev/null | \
312            sed -e "s/$_scp_path_esc/\\\\&/g" -e '/[^\/]$/d' -e "s/^/$1/") )
313    else
314        COMPREPLY+=( $( command ls -aF1dL $cur* 2>/dev/null | \
315            sed -e "s/$_scp_path_esc/\\\\&/g" -e 's/[*@|=]$//g' \
316            -e 's/[^\/]$/& /g' -e "s/^/$1/") )
317    fi
318}
319
320# scp(1) completion
321#
322_scp()
323{
324    local cur prev words cword
325    _init_completion -n : || return
326
327    local configfile prefix
328
329    _ssh_suboption_check && {
330        COMPREPLY=( "${COMPREPLY[@]/%/ }" )
331        return 0
332    }
333
334    case $prev in
335        -l|-P)
336            return 0
337            ;;
338        -F|-i|-S)
339            _filedir
340            compopt +o nospace
341            return 0
342            ;;
343        -c)
344            _ssh_ciphers
345            COMPREPLY=( "${COMPREPLY[@]/%/ }" )
346            return 0
347            ;;
348        -o)
349            _ssh_options
350            return 0
351            ;;
352    esac
353
354    _expand || return 0
355
356    case $cur in
357        !(*:*)/*|[.~]*) ;; # looks like a path
358        *:*) _scp_remote_files ; return 0 ;;
359    esac
360
361    if [[ "$cur" == -F* ]]; then
362        cur=${cur#-F}
363        prefix=-F
364    else
365        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
366        set -- "${words[@]}"
367        while [[ $# -gt 0 ]]; do
368            if [[ $1 == -F* ]]; then
369                if [[ ${#1} -gt 2 ]]; then
370                    configfile="$(dequote "${1:2}")"
371                else
372                    shift
373                    [[ $1 ]] && configfile="$(dequote "$1")"
374                fi
375                break
376            fi
377            shift
378        done
379
380        case $cur in
381            -*)
382                COMPREPLY=( $( compgen -W '$( _parse_usage "${words[0]}" )' \
383                    -- "$cur" ) )
384                COMPREPLY=( "${COMPREPLY[@]/%/ }" )
385                return 0
386                ;;
387            */*|[.~]*)
388                # not a known host, pass through
389                ;;
390            *)
391                _known_hosts_real -c -a -F "$configfile" "$cur"
392                ;;
393        esac
394    fi
395
396    _scp_local_files "$prefix"
397
398    return 0
399} &&
400complete -F _scp -o nospace scp
401
402# ex: ts=4 sw=4 et filetype=sh