SSH 構成ホストオートコンプリートコマンドはオートコンプリートされません。

SSH 構成ホストオートコンプリートコマンドはオートコンプリートされません。

ワイルドカードホストをインポートせずにSSH構成からホストをインポートする関数を作成しました。

sshConfAutoComplete() { 
   cat ~/.ssh/config | \
   grep 'host '      | \
   sed '
     s#.*\*##g; 
     s#host ##g
   '
}

出力:

pi
lynx
iridium
batchelorantor
rasp

出力が正しいため、この機能を次に追加しました。 /usr/local/etc/bash_completion.d/ssh

このように:

sshConfAutoComplete() { 
   cat ~/.ssh/config | \
   grep 'host '      | \
   sed '
     s#.*\*##g; 
     s#host ##g
   '
}
complete -F sshConfAutoComplete ssh

その後、次のソースを追加しました. /usr/local/etc/bash_completion.d/ssh~/.bash_profile

~/bash_profile次のように入力するとSourcedssh <tab>が表示されます。

pi
lynx
iridium
batchelorantor
rasp

入力するとオートコンプリートされssh ly <tab>ず、lynx上記の内容のみが出力されます。

どうすれば解決できますか?

答え1

man bashタイトルにプログラム可能な完成呼び出された関数が-F配列変数に一致する結果を提供する方法を説明しましたCOMPREPLY。通常、コマンドによって提供される完全なリストはsed コマンドに渡され、その単語をターゲット単語(たとえば関数の引数2())と一致させようcompgen -Wとします。$2少し単純化すると、次のような結果が得られます。

sshConfAutoComplete() { 
   COMPREPLY=( $(compgen -W \
    "$(sed -n ' /host /{s#.*\*##g; s#host ##g; p} ' ~/.ssh/config)" -- "$2"))
}
complete -F sshConfAutoComplete ssh

MacOSでは標準sedコマンドは許可されていないため、;各コマンドは改行でなければなりません。

   COMPREPLY=( $(compgen -W \
    "$(sed -n '/^host /{
     s#.*\*##g
     s#host ##g
     p
    }' ~/.ssh/config)" -- "$2"))

答え2

私はこれを行い、これを私のものに追加しました~/bash_profile

IFS=$'\n'

getSshConfHosts() {                                                                                                                                              
  grep    '^host' ~/.ssh/config  | \                                                                                                                                  
  grep -v '[?*]'                 | \                                                                                                                                      
  cut -d ' ' -f 2-                                                                                                                                       
}

sshConfAutoComplete() {                                                                                                                                          
    local cur prev opts                                                                                                                                                                
    cur=${COMP_WORDS[COMP_CWORD]}                                                                                                                                                                  
    prev=${COMP_WORDS[COMP_CWORD-1]}                                                                                                                                  
    opts=$(getSshConfHosts)                                                                                                                                                       
    COMPREPLY=( $(compgen -W "$opts" -- $cur ) )                                                                                                     
}         
complete -F sshConfAutoComplete ssh

以前のsedコマンドを削除すると空白行が残りました。host *

修正する

この答えはうまくいきましたが、彼は私がMacにいることを知らず、最初に書かなかったので、許可された答えにそれを与えました。彼のバージョンは理解しやすいです。

私は他の関数で正規表現部分を使用しているので、私の関数では次のようになりますbash_profile

IFS=$'\n'

getSshConfHosts() {
   sed -n '/^host /{
     s#.*\*##g
     s#host ##g; p
   }' ~/.ssh/config
}

sshConfAutoComplete() {
    local wordList
    wordList=$(getSshConfHosts)
    COMPREPLY=( $(compgen -W "$wordList" -- $2 ) )
}
complete -F sshConfAutoComplete ssh

関連情報