我有一个特定于项目的安装文件,我在运行 gnu screen 之前获取该文件。
在该文件中,我为测试命令和相关测试设置了 bash 完成。
看起来像这样:
$PROJECT_HOME/app/bin/lib/behat_suites.sh # _behat_suites() defined here
complete -F _behat_suites run_behat_suite
export -f _behat_suites
问题是,每个屏幕都是一个新的 shell,并且complete -F
设置无法保留(环境的其余部分会保留 - 它们是正确的子 shell)。
这export
意味着该函数会保留到屏幕子 shell 中,但完成设置本身不会。
缺少像 direnv 这样的工具,或者将设置放在我的用户 ~/.bashrc 中,有没有办法让子 shell 进程继承完成设置?
答案1
我没有看到任何方法可以轻松地做到这一点。您必须将complete -p
父 shell 的输出传递给子 shell。
首先,您可以向子 shell 注入额外的命令:
$ bash --rcfile <(echo '. ~/.bash_profile')
现在,如果我们尝试介绍complete -p
这一点,如下所示:
$ bash --rcfile <(echo '. ~/.bash_profile'; while read line; do echo "$line"; done < <(complete -p))
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
它几乎可以工作,它似乎在输入命令时被绊倒complete
。尝试使用文件作为中间体也不起作用:
$ complete -p > /tmp/cmp.txt; bash --rcfile <(echo '. ~/.bash_profile'; echo '. /tmp/cmp.txt')
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
试图找出它失败的原因并没有真正为事情提供更多的线索。在这里,我通过以下方式启用 bash 的详细输出-set -x
:
$ bash
$ set -x
然后我们获取我们刚才创建的文件:
$ . /tmp/cmp.txt
+ . /tmp/cmp.txt
++ complete -F _manila manila
++ complete -F _minimal
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
++ complete -F _command time
++ complete -F _command do
++ complete -o bashdefault -o default -o nospace -F __git_wrap_git_checkout gcob
因此,除非有一些聪明之处,否则在这种特殊情况下,输出中包含的数据似乎complete -p
不可移植。
参考
答案2
你不必把全部~/.bashrc 中的设置,但您可以添加一个“one-liner”来查看该_behat_suites
函数是否已定义和
补全函数有不是已定义;如果是这样,则定义完成。
这是一行行,为了便于阅读而进行了一些分解:
declare -f _behat_suites >/dev/null &&
! complete -p run_behat_suite >/dev/null &&
complete -F _behat_suites run_behat_suite