-1

I've wrote a simple bash completion script to complete ssh servernames from a list, eg:

_ssh() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(cat $hosts | awk -F';' '{print $2}')

    COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
    return 0
}
complete -F _ssh ssh

the $opts list is sth like:

locationX-apache-01.local.lan
locationY-apache-02.local.lan
locationX-mysql-01.local.lan
locationY-mysql-02.local.lan

Bash completion is working as expected if I write eg $ ssh loca<TAB> ... But how can I get suggestions if I don't start from the beginning like this: $ ssh apac<TAB> to get the 2 apache servers from the list above:

locationX-apache-01.local.lan
locationY-apache-02.local.lan
pynexj
  • 19,215
  • 5
  • 38
  • 56
jonny
  • 9
  • 6
  • Don't forget about a possible `ssh user@host`. You'll need to split `$cur` in `user` and `host` parts, match the `host`, then append the `user` to the result. – Fravadona Nov 08 '21 at 19:29
  • Put your hosts in your `.ssh/config` file and the default bash completion will pick them up and use them. – KamilCuk Nov 08 '21 at 20:11

1 Answers1

2

Try the following:

: ${cur:="."}
COMPREPLY=( $( grep "$cur" "$hosts"  | awk -F';' '{print $2}' ) )

The first line sets cur to "." (the regexp wildcard) in case it's not set. Then we just look for any matching string in the $hosts file. The functionality will feel a little different to end users, but I think this will give you what you are looking for.

Combining my edit with your code you get:

_ssh() 
{
    local cur 
    cur="${COMP_WORDS[COMP_CWORD]}"
    : ${cur:="."}
    COMPREPLY=( $( grep "$cur" "$hosts"  | awk -F';' '{print $2}' ) )

    return 0
}
complete -F _ssh ssh
Mark
  • 4,249
  • 1
  • 18
  • 27
  • Unfortunately this seems not like the solution… I am using zsh, is there a better way with zsh autocompletion maybe? – jonny Nov 09 '21 at 11:38