8

Bash Completionファイル内で、外部スクリプトによって完了文字列を検索しています。これには時間がかかります(1〜2秒)。これらの文字列は、現在のシェルが実行されている間はほとんど同じままなので、キャッシュしたいと思います。次にBashの完了がトリガーされたときに、高価なルックアップの代わりにキャッシュされた文字列を使用して、完了するようにする必要があります。 2回目に実行するとすぐに。

完了ファイルで感じをつかむために、ここに完了ファイルの重要な部分があります:

getdeployablefiles()
{
  # How can i cache the result of 'pbt getdeployablefiles'
  # for the time the current shell runs? 
  echo `pbt getdeployablefiles`
}

have pbt &&
_pbt_complete()
{
  local cur goals

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  goals=$(getdeployablefiles)
  COMPREPLY=( $(compgen -W "${goals}" -- $cur) )
  return 0
} &&
complete -F _pbt_complete pbt

シェルセッションの残りの部分でgetdeployablefilesの出力をキャッシュするにはどうすればよいですか?ここにある種のグローバル変数、または他のトリックが必要です。

解決:

goals非ローカルにして、設定されているかどうかを尋ねるだけでした。最終的なスクリプト:

getdeployablefiles()
{
  echo `pbt getdeployablefiles`
}

have pbt &&
_pbt_complete()
{
  local cur 
  if [ -z "$_pbt_complete_goals" ]; then
    _pbt_complete_goals=$(getdeployablefiles)
  fi

  _pbt_complete_goals=$(getdeployablefiles)

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W "${_pbt_complete_goals}" -- $cur) )
  return 0
} &&
complete -F _pbt_complete pbt
4

3 に答える 3

8

goalsステートメントを省略してlocal、名前が衝突する可能性が低い名前に変更してみ ませ_pbt_complete_goalsんか?次に、それがnullか未設定かを確認し、必要に応じて設定します。

于 2011-03-16T16:14:52.257 に答える
1

キャッシュされた値を現在のシェルのPIDを使用してファイルに書き込み、それをソースにして、PIDが一致することを確認できます。含まれている場合は、キャッシュされた値を使用します。そうでない場合は、再計算します。

于 2011-03-16T16:25:41.627 に答える
1

検討できるアプローチの1つはbkt、データをキャッシュするために使用することです。何かのようなもの:

_pbt_complete() {
  local cur=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W "$(bkt --ttl=10m -- pbt getdeployablefiles)" -- "$cur") )
}

動作するはずです。これにより、キャッシュミスが発生するたびにbkt呼び出すすべてのキャッシュロジックがオフロードされます。pbtまた、シェルセッション間でも機能するため、可変スコープなどに取り組む必要はありません。

キャッシュを特定のシェルセッションに制限する場合は、渡すことができます(現在--scope="_pbt_complete_$$"$$PIDに拡張されます)。

また、バックグラウンドでキャッシュを更新する場合は、キャッシュがウォームであるが古い場合に非同期--stale=1mで呼び出すために渡すことができます。pbt明らかに、適切と思われる期間--ttl--stale期間を調整できます。

免責事項:私はの作者ですbkt

于 2021-10-29T21:42:48.947 に答える