Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash脚本中的自动完成_Bash_Autocomplete - Fatal编程技术网

bash脚本中的自动完成

bash脚本中的自动完成,bash,autocomplete,Bash,Autocomplete,我正在尝试在bash脚本中自动完成文件夹名称。如果我输入一个完整的文件夹名称,一切正常,但我不知道如何自动完成名称。有什么想法吗 repo() { cd ~/Desktop/_REPOS/$1 } 我试着通过阅读寻找灵感,但很快就迷失了方向,因为我对bash还相当陌生 目标(在my bashrc中包含上述回购函数): 实际上,您可以从以下方面借用大量代码: for循环迭代目录中以作为\u repo\u complete函数第二个参数的字符串开头的所有文件(这是要自动完成的字符串) 将代码添加

我正在尝试在bash脚本中自动完成文件夹名称。如果我输入一个完整的文件夹名称,一切正常,但我不知道如何自动完成名称。有什么想法吗

repo() {
 cd ~/Desktop/_REPOS/$1
}
我试着通过阅读寻找灵感,但很快就迷失了方向,因为我对bash还相当陌生

目标(在my bashrc中包含上述回购函数):


实际上,您可以从以下方面借用大量代码:

for
循环迭代目录中以作为
\u repo\u complete
函数第二个参数的字符串开头的所有文件(这是要自动完成的字符串)


将代码添加到您的
.bashrc
中,它应该可以工作

实际上,您可以从以下方面借用大量代码:

for
循环迭代目录中以作为
\u repo\u complete
函数第二个参数的字符串开头的所有文件(这是要自动完成的字符串)


将代码添加到您的
.bashrc
中,它应该可以工作

如果我理解正确,我可以看到两个选项来获取您想要的内容,即自定义
cd
命令的路径自动完成

  • 您可以将父目录
    ~/Desktop/\u REPOS
    添加到
    CDPATH
    环境变量中:

    CDPATH="$CDPATH":"$HOME"/Desktop/_REPOS
    
    现在,您可以在任何目录中键入
    cd
    SpaceTab,除当前目录的子目录外,
    ~/Desktop/\u REPOS
    中的所有目录都将显示出来。(这也是这种方法的缺点:更混乱。)

  • 您可以在
    .bashrc
    中添加完成函数。按照开始的方式,您需要
    ~/Desktop/\u REPOS
    中所有目录的基本名称。要获得目录的自动完成,我们可以使用
    compgen-d
    内置:

    $ compgen -d "$HOME"/Desktop/_REPOS/
    /home/me/Desktop/_REPOS/folder1
    /home/me/Desktop/_REPOS/folder2
    /home/me/Desktop/_REPOS/stackstuff
    /home/me/Desktop/_REPOS/hellofolder
    
    这将返回所有子目录的名称。当路径更具体时,它将减少到更少的候选路径:

    $ compgen -d "$HOME"/Desktop/_REPOS/f
    /home/me/Desktop/_REPOS/folder1
    /home/me/Desktop/_REPOS/folder2
    
    要删除除基名以外的所有内容,我们使用shell参数扩展,如下所示:

    $ arr=(/path/to/dir1 /path/to/dir2)
    $ echo "${arr[@]##*/}"
    dir1 dir2
    
    参数展开中的
    ##*/
    arr
    的每个元素中删除最长的
    */
    匹配项,即只保留最后一个正斜杠后面的内容–这正是我们想要的

    现在我们将其组合成一个函数:

    _comp_repo () {
        # Get list of directories
        # $2 is the word being completed
        COMPREPLY=($(compgen -d "$HOME"/Desktop/_REPOS/"$2"))
    
        # Reduce to basenames
        COMPREPLY=("${COMPREPLY[@]##*/}")
    }
    
    这将进入您的
    .bashrc
    ,以及使用它进行
    repo
    自动完成的说明:

    complete -F _comp_repo repo
    
    请注意,
    repo
    函数应该引用
    $1
    参数,以确保它正确处理带有特殊字符(空格、制表符…)的目录名:

    repo () {
        cd ~/Desktop/_REPOS/"$1"
    }
    
  • 您点击选项卡的次数取决于,例如
    如果不明确,则显示全部


    参考资料

    • Bash手册

    如果我理解正确,我可以看到两个选项来获取您想要的内容,即自定义
    cd
    命令的路径自动完成

  • 您可以将父目录
    ~/Desktop/\u REPOS
    添加到
    CDPATH
    环境变量中:

    CDPATH="$CDPATH":"$HOME"/Desktop/_REPOS
    
    现在,您可以在任何目录中键入
    cd
    SpaceTab,除当前目录的子目录外,
    ~/Desktop/\u REPOS
    中的所有目录都将显示出来。(这也是这种方法的缺点:更混乱。)

  • 您可以在
    .bashrc
    中添加完成函数。按照开始的方式,您需要
    ~/Desktop/\u REPOS
    中所有目录的基本名称。要获得目录的自动完成,我们可以使用
    compgen-d
    内置:

    $ compgen -d "$HOME"/Desktop/_REPOS/
    /home/me/Desktop/_REPOS/folder1
    /home/me/Desktop/_REPOS/folder2
    /home/me/Desktop/_REPOS/stackstuff
    /home/me/Desktop/_REPOS/hellofolder
    
    这将返回所有子目录的名称。当路径更具体时,它将减少到更少的候选路径:

    $ compgen -d "$HOME"/Desktop/_REPOS/f
    /home/me/Desktop/_REPOS/folder1
    /home/me/Desktop/_REPOS/folder2
    
    要删除除基名以外的所有内容,我们使用shell参数扩展,如下所示:

    $ arr=(/path/to/dir1 /path/to/dir2)
    $ echo "${arr[@]##*/}"
    dir1 dir2
    
    参数展开中的
    ##*/
    arr
    的每个元素中删除最长的
    */
    匹配项,即只保留最后一个正斜杠后面的内容–这正是我们想要的

    现在我们将其组合成一个函数:

    _comp_repo () {
        # Get list of directories
        # $2 is the word being completed
        COMPREPLY=($(compgen -d "$HOME"/Desktop/_REPOS/"$2"))
    
        # Reduce to basenames
        COMPREPLY=("${COMPREPLY[@]##*/}")
    }
    
    这将进入您的
    .bashrc
    ,以及使用它进行
    repo
    自动完成的说明:

    complete -F _comp_repo repo
    
    请注意,
    repo
    函数应该引用
    $1
    参数,以确保它正确处理带有特殊字符(空格、制表符…)的目录名:

    repo () {
        cd ~/Desktop/_REPOS/"$1"
    }
    
  • 您点击选项卡的次数取决于,例如
    如果不明确,则显示全部


    参考资料

    • Bash手册

    如果我想删除
    repo()
    函数并将代码放入
    \u repo\u complete
    (只获取一个函数),我该怎么做?我能把最后一行改为
    complete-F\u repo\u complete
    ?我认为这不实用,因为每次尝试自动完成时都会调用
    \u repo\u complete
    函数。你可以通过检查是否已经有一个有效的目录名来解决这个问题,但我认为这不值得保存一个函数。你可能不需要将它添加到
    .bashrc
    。根据,用户完成脚本来源于
    ~/.local/share/bash completion/completions/
    ;此目录可由用户创建。至少在Ubuntu上,系统完成脚本通常存储在
    /usr/share/bash completion/completions/
    中。如果我想删除
    repo()
    函数并将代码放入
    \u repo\u complete
    中(只获取一个函数),我该怎么做?我是否可以将最后一行更改为
    complete-F\u repo\u complete
    ?我认为这不实际,因为每次尝试自动完成时都会调用
    \u repo\u complete
    函数。你可以通过检查是否已经有一个有效的目录名来绕过这个问题,但我认为