我试图为文件名实现bash完成,其中名称列表由另一个程序检索(例如通过网络拉取)。我几乎可以使用它,但自动转义会给我带来一些问题。下面的代码是我能够讨论的最简单的问题:
#!/bin/bash
_myscript()
{
local IFS=$'
'
# Debugging:
#echo
#echo "./myscript $COMP_CWORD ${COMP_WORDS[@]}"
COMPREPLY=( $(./myscript $COMP_CWORD ${COMP_WORDS[@]})
}
complete -o filenames -F _myscript myscript
此脚本使用文件名myscript
模拟实际可以检索文件名的程序:
#!/bin/bash
index=$(( $1 + 2 ))
cat matches.txt | fgrep "${!index}"
上面引用的matches.txt
文件是:
abc
def
ghi=jkl
mnl opq
因此,如果您只输入前几个字符,那么正确选项卡会完成所有内容,从而产生我想要的转义:
./myscript 1 ./myscript gh<TAB> -> ... ghi\=jkl
./myscript 1 ./myscript mn<TAB> -> ... mnl\ opq
问题是在等于或空格之后的标签时,它无法完成:
./myscript 1 ./myscript ghi\=j<TAB> (no change)
./myscript 1 ./myscript mnl\ o<TAB> (no change)
使用调试它似乎是向myscript发送以下命令(由我添加的引号仅表示分组,因为它没有显示在echo语句中):
./myscript 1 ./myscript 'ghi\=j'
./myscript 1 ./myscript 'mnl\ o'
这意味着我的fgrep正在搜索实际包含转义字符的文件名。需要一段时间才能达到这一点,但真正的问题是:
为什么它会向我提供我正在填写的文字的转义版本?当我最终按下回车按钮时,转义将由bash解释,myscript
不会收到它们。因此,我在接收标签时所收到的内容与用户实际按下输入时收到的内容之间似乎存在差异。
我真的不明白为什么$COMP_WORDS
被设置为包含转义的版本,当我的理解是数组是分隔参数的时候,所以似乎转义是不必要的。是否有一个有用的功能可以安全地消除这些逃逸,或者我的整个方法是错误的?