相关疑难解决方法(0)

在Bash完成的上下文中关于$ {array [*]}与$ {array [@]}的混淆

我正在尝试第一次编写Bash完成,我对解除引用Bash数组(${array[@]}${array[*]})的两种方法感到困惑.

这是相关的代码块(顺便说一句,它可以工作,但我想更好地理解它):

_switch()
{
    local cur perls
    local ROOT=${PERLBREW_ROOT:-$HOME/perl5/perlbrew}
    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    perls=($ROOT/perls/perl-*)
    # remove all but the final part of the name
    perls=(${perls[*]##*/})

    COMPREPLY=( $( compgen -W "${perls[*]} /usr/bin/perl" -- ${cur} ) )
}
Run Code Online (Sandbox Code Playgroud)

Bash的文档说:

可以使用$ {name [subscript]}引用数组的任何元素.需要大括号以避免与shell的文件名扩展运算符冲突.如果下标是'@'或'*',则该单词将扩展为数组名称的所有成员.这些下标仅在单词出现在双引号内时有所不同.如果单词是双引号,则$ {name [*]}扩展为单个单词,每个数组成员的值由IFS变量的第一个字符分隔,$ {name [@]}扩展名称的每个元素一个单独的词.

现在我想我明白,compgen -W期望一个字符串包含可能的替代词列表,但在这种情况下,我不明白"$ {name [@]}将名称的每个元素扩展为单独的词"是指.

长话短说:${array[*]}作品; ${array[@]}没有.我想知道为什么,我想更好地理解究竟是什么${array[@]}扩展到了什么.

arrays bash bash-completion

73
推荐指数
2
解决办法
3万
查看次数

正确处理bash完成中的空格和引号

在bash完成中处理空格和引号的正确/最佳方法是什么?

这是一个简单的例子.我有一个命令words(例如,字典查找程序),它将各种单词作为参数.支持的"单词"实际上可能包含空格,并在名为的文件中定义words.dat:

foo
bar one
bar two
Run Code Online (Sandbox Code Playgroud)

这是我的第一个建议的解决方案:

_find_words()
{
search="$cur"
grep -- "^$search" words.dat
}

_words_complete()
{
local IFS=$'\n'

COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"

COMPREPLY=( $( compgen -W "$(_find_words)" -- "$cur" ) )

}
complete -F _words_complete words
Run Code Online (Sandbox Code Playgroud)

‘words f<tab>’正确键入完成命令‘words foo ’(带尾随空格),这很好,但‘words b<tab>’它建议‘words bar ’.正确的完成将是‘words bar\ ’.而对于‘words "b<tab>’‘words 'b<tab>’它不提供建议.

这是我能够解决的最后一部分.可以使用eval正确解析(转义)字符.然而,eval是不是喜欢缺失报价的,所以要得到的一切工作,我不得不改变search="$cur",以

search=$(eval echo "$cur" 2>/dev/null ||
eval echo "$cur'" 2>/dev/null …
Run Code Online (Sandbox Code Playgroud)

bash quotes eval autocomplete escaping

26
推荐指数
3
解决办法
6376
查看次数

标签 统计

bash ×2

arrays ×1

autocomplete ×1

bash-completion ×1

escaping ×1

eval ×1

quotes ×1