用户定义的bash_completion.d脚本的标准位置?


47

我对Linux(Suse)机器具有用户访问权限(没有root用户),在其中我开发了一些bash脚本和相应的bash自动完成规则。

由于脚本仅属于我的用户,因此我只需要对我“活动”的完整规则(部分原因是我没有root写入权限),/etc/bash_completion.d/因此无法将bash_completion脚本放入文件夹中。

目前,我为文件命名.bash_completion.myscript并直接从我的文件中获取文件.bashrc,但是我只是想知道是否还有其他“标准”方式来实现这些结果,而bash实现中已经考虑过这种方式。

例如,创建一个文件夹/home/myuser/.bash_completion.d/

Answers:


36

使用~/.bash_completion文件。

Bash完成常见问题解答中

问:如何在
每次发行新版本时都不必重新插入我自己的本地完成内容?

A.将它们放在〜/ .bash_completion中,该文件在
主完成脚本的末尾进行解析。另请参阅下一个问题。

问:我编写/维护软件包X,并希望维护
此软件包的我自己的完成代码。我应该在哪里放置它以确保
交互式bash shell可以找到并获取它?

答:将其安装在
bash-completion的pkgconfig文件变量指向的目录之一中。有两种
选择:推荐的一种是'completionsdir'(用
“ pkg-config --variable = completionsdir bash-completion”来获取),
根据调用的命令的名称从中按需加载完成,
因此请确保命名您的完成文件,并
在文件提供
多个命令完成的情况下包含例如符号链接。出于
向后兼容性原因而出现的另一个是“ compatdir”(通过
“ pkg-config --variable = compatdir bash-completion” 获得它)


在询问之前,我在serverfault中进行了很多搜索,但没有考虑最基本的步骤:RTFM!非常感谢您的回复!
卡莱斯·萨拉

4
可能希望指定.bash_completion是文件而不是目录。由于bash_completion.d我是一个目录,所以我认为我只能在scp本地bash_completion.d将其命名为远程服务器上的目录,但是在下一次登录时,它告诉我必须是一个文件。
NobleUplift '16

3
@NobleUplift Bash完成常见问题解答已更改,现在包含有关从目录中按需加载用户的Bash完成内容的方式的信息。这似乎至少在bash-completion 2.8版中有效,但在2.1版中无效。目录中的文件应与命令名称完全相同,否则,可以使用符号链接。
jarno

@jarno我为系统中的所有自定义程序和脚本编写了bash结束脚本,但我的高级开发人员将它们击倒了:(
NobleUplift

@NobleUplift为什么?您仍然可以自己使用它们。
佳诺

49

这是本地用户如何拥有工作~/.bash_completion.d/目录的方式。

  1. 编辑文件:nano ~/.bash_completion,添加以下内容:

    for bcfile in ~/.bash_completion.d/* ; do
      . $bcfile
    done
  2. 制作目录: mkdir ~/.bash_completion.d

  3. 编辑文件:~/.bash_completion.d/myscript,添加以下内容:

    _myscript_tab_complete () {
        local cur prev opts
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        words="-f -h --etc"
    
        COMPREPLY=( $(compgen -W "${words}" -- ${cur}) )
        return 0
    }
    complete -F _myscript_tab_complete myscript
  4. 源.bash_completion: . ~/.bash_completion

更新资料

如果您预期~/.bash_completion.d/目录为空,并且希望避免看到错误消息bash: /home/<username>/.bash_completion.d/*: No such file or directory,请使用添加文件类型test [ -f "$bcfile" ]

for bcfile in ~/.bash_completion.d/* ; do
  [ -f "$bcfile" ] && . $bcfile
done

2

Russell E Glaue回答很好,但~/.bash_completion还不完整。

问题是何时~/.bash_completion.d/为空,随后for f in ~/.bash_completion.d/*显示以下错误消息:

-bash:/home/user/.bash_completion.d/*:没有这样的文件或目录

最简单的可移植解决方案是如果目录为空,则跳过循环:

if [[ -d ~/.bash_completion.d/ ]] && \
   ! find ~/.bash_completion.d/. ! -name . -prune -exec false {} +
then
    for f in ~/.bash_completion.d/*
    do
        source "$f"
    done
fi

1

一个更简单的解决方案是使用nullglob选项。虽然这不是可移植的,但bash补全也不是。因此,可移植性无关紧要。

另外,在采购时,您将需要在变量周围使用引号。这可以处理文件包含其他其他特殊字符的空格的情况。

shopt -s nullglob

for f in ~/.bash_completion.d/*; do
  [ -f "$f" ] && . "$f"
done

1
仅供参考,对于显示的内容(即nullglob)的解释(或链接到文档)对读者很有帮助。
Cometsong

1

至少包含bash-completion 2.8和更高版本的enable选项,以将本地Bash补全放置在目录中

${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions

完成文件名或符号链接名必须与相应的命令名匹配。这些完成仅按需加载。存储在文件 ~/.bash_completion中的完成内容总是被加载。

参考:请参阅“问:我应该在哪里安装自己的本地完成?” 在https://github.com/scop/bash-completion/blob/master/README.md中

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.