如何缓存当前会话的Bash完成脚本中使用的变量

Ing*_*her 6 bash bash-completion

在我的Bash Completion文件中,我正在通过外部脚本查找完成字符串,这需要一些时间(1-2秒).由于这些字符串在当前shell运行的其余时间内大部分保持不变,我想缓存它们,并且当下次触发Bash完成时,它应该使用缓存的字符串而不是昂贵的查找,以便它完成第二次运行时立即.

要通过完成文件获得感觉,这是完成文件的重要部分:

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
Run Code Online (Sandbox Code Playgroud)

如何在shell会话的其余部分缓存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
Run Code Online (Sandbox Code Playgroud)

Pau*_*ce. 7

为什么不留goals出的local声明,并与名称冲突的可能性低重命名为, _pbt_complete_goals也许?然后你可以检查它是否为空或未设置并在必要时设置它.


dim*_*414 1

您可以考虑的一种方法是bkt为您缓存数据。就像是:

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

应该管用。这将所有缓存逻辑卸载到bktpbt这会卸载每当缓存未命中时调用的它还可以跨 shell 会话工作,因此您无需费力处理变量范围等问题。

如果你将缓存限制在给定的 shell 会话中,你可以通过--scope="_pbt_complete_$$"$$扩展为当前 PID)。

如果您想在后台刷新缓存,您可以在缓存处于热状态但旧时异步--stale=1m调用。pbt显然你可以调整--ttl--stale根据需要

免责声明:我是以下内容的作者bkt