数组 – 在Bash完成的上下文中对${array [*]}和${array [@]}的混淆

前端之家收集整理的这篇文章主要介绍了数组 – 在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} ) )
}

Bash的documentation says

@H_404_7@

Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid conflicts with the shell’s filename expansion operators. If the subscript is ‘@’ or ‘*’,the word expands to all members of the array name. These subscripts differ only when the word appears within double quotes. If the word is double-quoted,${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS variable,and ${name[@]} expands each element of name to a separate word.

现在我想我理解compgen -W期望一个字符串包含可能的替代品的wordlist,但在这个上下文中,我不明白什么“$ {name [@]}扩展名称的每个元素到一个单独的单词”的意思。

长故事:$ {array [*]}工作; $ {array [@]}不。我想知道为什么,我想更好地理解$ {array [@]}扩展到什么。

(这是我对Kaleb Pederson的回答的扩展 – 看看对[@] vs [*]的更一般的对待)

当Bash(或任何类似的shell)解析命令行时,它将它分成一系列“单词”(我将称为“shell单词”,以避免以后混淆)。通常,字词由空格(或其他空格)分隔,但是空格可以通过转义或引用而包括在单词中。双引号中[@]和[*] – 展开数组之间的区别是,“$ {myarray [@]}”导致数组的每个元素被视为单独的shell-word,而“$ {myarray [ *]}“结果是一个单独的shell-word,数组的所有元素都用空格(或IFS的第一个字符)分隔。

通常,[@]行为是你想要的。假设我们有perls =(perl-one perl-two)并使用ls“$ {perls [*]}” – 这相当于ls“perl-one perl-two”,它将寻找单个文件名为perl-one perl-two,这可能不是你想要的。 ls“$ {perls [@]}”等价于ls“perl-one”“perl-two”,这更有可能做一些有用的事情。

提供一个完成词列表(我将称之为comp-words以避免与shell-words混淆)到compgen是不同的; -W选项接受一个复合词列表,但它必须是一个单独的壳单词的形式,复合词用空格分隔。注意,接受参数的命令选项总是(至少就我所知)采用一个shell-word – 否则没有办法告诉选项的参数何时结束,以及常规的命令参数(/ other选项标志)开始。

更详细:

perls=(perl-one perl-two)
compgen -W "${perls[*]} /usr/bin/perl" -- ${cur}

相当于compgen -W“perl-one perl-two / usr / bin / perl” – $ {cur},它可以做你想要的。另一方面,

perls=(perl-one perl-two)
compgen -W "${perls[@]} /usr/bin/perl" -- ${cur}

相当于compgen -W“perl-one”“perl-two / usr / bin / perl” – $ {cur},这是完全无意义的:“perl-one”是唯一的附加到-W标志,而第一个真实参数 – 即compgen将作为要完成的字符串 – 是“perl-two / usr / bin / perl”。我期望compgen抱怨它已经被给予额外的参数(“ – ”和任何在$ cur),但显然它只是忽略了他们。

原文链接:https://www.f2er.com/bash/389589.html

猜你在找的Bash相关文章