为 getopts 中解析的参数启用自动完成

jus*_*482 3 bash autocomplete getopts

我有一个 bash 脚本,用于getopts解析命令行参数。其中一个参数-l <name>针对if确定某些设置的语句。是否可以在命令行中进行自动完成工作以输入<name>参数的工作?

这是我的脚本的命令行解析部分 ( getopts):

while getopts 'l:r:m:?h' c
do
  case $c in
    l) 
        library=$OPTARG 
        ;;
    r)  
        rename_config=$OPTARG 
        ;;
    m)  
        align_mm=$OPTARG
        ;;  
    h|?) usage 
        ;;
  esac
done
Run Code Online (Sandbox Code Playgroud)

库选项 ( -l) 指的是脚本的这一部分:

if [ $library = "bassik" ];
    then
        read_mod="clip"
        clip_seq="GTTTAAGAGCTAAGCTGGAAACAGCATAGCAA"
        echo "Bassik library selected"
elif [ $library = "moffat_tko1" ];
    then
        read_mod="trim"
        sg_length=20    
        echo "Moffat TKO1 library selected"
elif [ $library = "sabatini" ];
    then
        read_mod="trim"
        sg_length=20    
        echo "Sabatini library selected"
fi
Run Code Online (Sandbox Code Playgroud)

自动补全应该起作用的部分是“bassik”、“moffat_tko1”和“sabatini”参数。到目前为止,我已经尝试过<TAB>在 后立即击球./script.sh -l,但这不起作用。我已经用谷歌搜索了它,但找不到任何适合我的情况的东西(也不知道如何称呼它,bash 的新手)。

Rac*_* K. 5

首先,我将脚本片段复制到名为auto.sh的文件中,并为其设置执行权限:

#!/bin/bash

while getopts 'l:r:m:?h' c
do
  case $c in
    l) 
        library=$OPTARG 
        ;;
    r)  
        rename_config=$OPTARG 
        ;;
    m)  
        align_mm=$OPTARG
        ;;  
    h|?) usage 
        ;;
  esac
done


if [ $library = "bassik" ];
    then
        read_mod="clip"
        clip_seq="GTTTAAGAGCTAAGCTGGAAACAGCATAGCAA"
        echo "Bassik library selected"
elif [ $library = "moffat_tko1" ];
    then
        read_mod="trim"
        sg_length=20    
        echo "Moffat TKO1 library selected"
elif [ $library = "sabatini" ];
    then
        read_mod="trim"
        sg_length=20    
        echo "Sabatini library selected"
fi
Run Code Online (Sandbox Code Playgroud)

然后,要为该选项设置自动完成-l,您可以从这些基本步骤开始(这可以在未来得到增强):

1.创建一个完成脚本(例如./auto-complete.sh),其中包含根据完成请求(完整命令的参数)调用的libs函数。如果option 是完成位置(参数)之前的单词,则该函数会触发库名称的显示(COMPREPLY数组变量的内容) :-F-l$3

function libs()
{
  # $1 is the name of the command 
  # $2 is the word being completed
  # $3 is the word preceding the word being completed

  case $3 in
    -l) COMPREPLY+=("bassi")
        COMPREPLY+=("moffat_tko1")
        COMPREPLY+=("sabatini");;
  esac
}

complete -F libs auto.sh
Run Code Online (Sandbox Code Playgroud)

2.在本地 shell 中获取脚本:

$ source ./auto-complete.sh
Run Code Online (Sandbox Code Playgroud)

3.启动 shell 脚本并TAB在选项后面的空格后键入两次 key -l

$ ./auto.sh -l <tab><tab>
bassik       moffat_tko1  sabatini
$ ./auto.sh  -l bassik
Bassik library selected
Run Code Online (Sandbox Code Playgroud)

4、上面系统地列出了键入key时的所有选择TAB。为了在输入第一个字母时获得更准确的补全,可以增强补全脚本以使用compgen命令:

$ source ./auto-complete.sh
Run Code Online (Sandbox Code Playgroud)

  • 太棒了,成功了!感谢您为回答付出如此多的努力。 (2认同)