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

3
我有一个使用getopts解析命令行参数的bash脚本。其中一个参数-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

图书馆选项(-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

自动完成功能应该适用于 "bassik"、 "moffat_tko1" 和 "sabatini" 这些参数。 到目前为止,我尝试在输入 ./script.sh -l 后立即按下 <TAB> ,但这并不起作用。 我已经搜索过了,但找不到符合我的情况的内容(不确定也如何调用此功能,对bash不熟悉)。

是的,这是可能的。基本上,自动完成脚本就是这样做的。 - KamilCuk
1
可以实现,但您需要提供更多具体信息 - 您的脚本名称是什么?自动完成选项是什么(它是单词列表还是以某种方式动态生成的)?您尝试过一些不起作用的方法吗? - Benjamin W.
感谢您的评论。我已经编辑了我的问题,使其更清晰。 - justinian482
1个回答

4

首先,我将您的脚本片段复制到一个名为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

接下来,要为-l选项设置自动补全功能,您可以从以下基本步骤开始(此功能可以进行进一步增强):

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

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

2. 在本地 shell 中引用脚本:

$ source ./auto-complete.sh

3. 运行shell脚本并在-l选项后的空格后按两次TAB键:

$ ./auto.sh -l <tab><tab>
bassik       moffat_tko1  sabatini
$ ./auto.sh  -l bassik
Bassik library selected

4. 当您按下TAB键时,前面列出了所有的选择。为了在输入首字母时获得更准确的补全,可以通过增强完成脚本使用compgen命令来实现:

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=($(compgen -W "bassik moffat_tko1 sabatini" "${COMP_WORDS[$COMP_CWORD]}"));;
  esac
}

complete -F libs auto.sh

1
太棒了,它起作用了!感谢您在回答中付出了如此多的努力。 - justinian482

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接