bash, zsh: 声明[*] (哦,我的)

4
我正在使用一个具有以下语法的Bash脚本:
$ declare -a THIS[*]

这似乎在zsh中是非法的(我得到了一个“没有找到匹配项:THIS [*]”错误)。有人能帮我将其翻译成zsh吗?
另外,[*]语法是什么意思?(我知道我们正在声明一个数组,但为什么要用[*]?)
更新
为了提供代码使用的示例并解释它的有效性,我从Eric Engstrom在password free ssh上的文章中复制了几行。
declare -a SSSHA_KEYS[*]

# --- PARSE ARGS --- #
sssha_parse_args() {
  local OPTIND=1
  while getopts "xe:k:t:" OPT; do
    #echo "$OPT $OPTARG $OPTIND"
    case $OPT in
      t) SSSHA_ARGS="-t $OPTARG" ;;
      e) SSSHA_ENV="$OPTARG" ;;
      k) [ -f "${OPTARG}" ] && SSSHA_KEYS[${#SSSHA_KEYS[*]}]="$OPTARG" ;;
      x) SSSHA_STOP_ON_EXIT=$OPT
    esac
  done
  shift $(($OPTIND - 1))

  # set default key, if none specified
  if [ -z "${SSSHA_KEYS[*]}" ]; then
    for key in $HOME/.ssh/id_[rd]sa; do
      [ -f "$key" ] && SSSHA_KEYS[${#SSSHA_KEYS[*]}]="$key"
    done
  fi
}

我认为[*]被用作某种动态迭代器(因为我们不知道它将来会有多少项)。我只想知道在zsh中等效的声明!

你说的 "(oh my)" 是什么意思? - Shahbaz
1
在zsh中,没有办法控制数组可以占用多少空间(除非你愿意将其设置为只读),所以尝试使用declare -a SSSHA_KEYS。根据@ormaaj的解释,这些声明应该是相等的。其他发布的代码可能不需要修改就能正常工作,除了SSSHA_KEYS [ $ {#SSSHA_KEYS [*]}] = smth:它将添加一个键,我是对的吗?使用SSHA_KEYS + =(smth),因为在zsh数组索引从1开始,ARR [ARR_LENGTH]将分配给最后一个项目,而不是在其后面。 - ZyX
1个回答

3
只有Bash有declare命令,ksh和zsh有typeset命令。在所有shell中,这些代码都是无意义的,因为各种shell对于像declaretypeset这样的声明命令的参数解析存在分歧(特别是在Bash中,-a会以一种特定的方式改变解析),因此在每个shell中执行的结果都会不同、难以预测,并且可能会带来潜在的危险。
具体来说,Bash是如何解释这段代码的——来自manpage:

也可以接受declare -a name[subscript]的形式;subscript将被忽略。

所以如果未加引号,如果当前目录中有一个名为THIS*的文件,则Bash会由于路径名扩展而抛出非法名称错误。否则,它只会创建一个名为“THIS”的空数组。 [*]的含义取决于上下文。在普通命令评估上下文中未加引号时,它是一个字符类,只匹配字面值星号。如果在数组名后面的参数扩展中使用,则将数组的所有元素扩展为一个单词,由IFS的第一个字符分隔。
在Bash中,declare命令声明变量、返回其值、设置属性并影响函数作用域。请参见:http://wiki.bash-hackers.org/commands/builtin/declare 编辑:鉴于现在问题中的示例,在Bash中的行为与上述描述相同。应该从declare中删除[*]。该代码还有许多其他问题,例如尝试将参数放入字符串中、使用全大写变量名以及在明显不打算在最小POSIX sh上运行的脚本中使用[而不是[[

Zsh确实有declare,但它是typeset的别名。注意:如果你执行emulate bash,然后执行declare -a THIS[*],那么当THIS未定义时,消息将会变成declare: THIS[*]: can't create local array elements,而当THIS被定义为declare -a THIS时,消息则会变成declare: THIS[*]: array elements must be scalar。我不知道declare -a THIS[*]在什么情况下被调用以及其作用是什么,因此无法提供更多信息。 - ZyX
“emulate bash” 和 “emulate sh” 是相同的。 - ZyX
@ZyX 是的,我应该猜到它有declare作为其兼容性特性之一。我可以想到一些仅限于Bash的边角情况,其中THIS [*]本身可能会出现,但它们绝对不是大多数人所知道或关心的事情,也绝对与此无关(例如,传递给unset的参数,大多数其他情况涉及间接扩展)。 - ormaaj
@ormaaj - 这里涉及到 THIS[*] 的情况是相关的, 因为我想知道它的意思。 - danodonovan
@danodonovan 没有更多的上下文,无法确定写这段话的人在想什么。他们可能不知道数组是如何工作的。我认为我已经回答过了。如果当前目录中恰好有名为 THIS* 的文件,则会出现非法名称错误。否则,在Bash中,当指定索引的同时声明一个空数组时,只会创建数组并忽略指定的索引,在使用 * 和非关联索引数组的情况下是无效的。无论如何,这不是任何人想要的东西。 - ormaaj

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