数组 – 在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:
现在我想我理解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),但显然它只是忽略了他们。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |