【问题标题】:bash, zsh : declare [*] (oh my)bash, zsh : 声明 [*] (天哪)
【发布时间】:2015-10-03 06:04:16
【问题描述】:

我正在使用具有以下语法的 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中的等效声明!

【问题讨论】:

  • “(哦,我的)”是什么意思?!
  • 没有办法控制数组在 zsh 中可以占用多少空间(除非您愿意将其设为只读),因此请尝试使用 declare -a SSSHA_KEYS。相信@ormaaj 的解释,这些声明应该是平等的。除了SSSHA_KEYS[${#SSSHA_KEYS[*]}]=smth 之外,其他发布的代码可能无需修改即可工作:它将添加一个密钥,对吗?使用 SSHA_KEYS+=( smth ),因为 zsh 数组索引从 1 开始,ARR[ARR_LENGTH] 将分配给最后一项,而不是在它之后。

标签: bash zsh


【解决方案1】:

只有 Bash 有 declare。 kshes 和 zsh 有typeset。该代码在所有这些代码中都是无意义的,并且由于 shell 不同意解析 声明命令 的参数,例如 declare 和 typeset(特别是 Bash,-a 在特定的方式),它会在每种情况下做不同的不可预测的、有潜在危险的事情。

具体来说,Bash 是如何解释这一点的——来自手册页:

declare -a name[subscript] 也被接受;下标被忽略。

因此,由于它没有被引用 - 如果当前目录中有一个名为 THIS* 的文件,那么由于路径名扩展,Bash 会抛出非法名称错误。否则它只会创建一个名为“THIS”的空数组。

[*] 的含义取决于上下文。在普通命令评估上下文中未引用,它是一个仅匹配文字星号的字符类。如果在数组名后面的参数扩展中使用,它将数组的所有元素扩展为一个由 IFS 的第一个字符分隔的单词。

declare 在 bash 中声明变量、返回它们的值、设置属性并影响函数范围。见:http://wiki.bash-hackers.org/commands/builtin/declare

edit:鉴于现在问题中的示例,在 bash 中的行为如上所述。应从declare 中删除[*]。该代码还有许多其他问题,例如尝试将参数放入字符串中,使用全大写变量名,以及在显然不打算在最小 POSIX sh 上运行的脚本中使用 [ 而不是 [[。

【讨论】:

  • Zsh 确实有declare,但它是排版的别名。注意:如果您执行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[*] 应该做什么以及在什么上下文中调用它,因此我无话可说。
  • * emulate bash 与 emulate sh 相同。
  • @ZyX 啊,是的,我应该猜到它有 declare 作为其兼容性功能的一部分。我可以想到一些仅适用于 Bash 的极端情况,THIS[*] 本身可能会出现,但它们绝对不是大多数人会知道或关心的事情,而且绝对与这里无关(例如,@987654347 的论点@,其他大多数涉及间接扩展)。
  • @ormaaj - 出现THIS[*] 的情况在这里很重要,因为我在问这意味着什么。
  • @danodonovan 如果没有更多上下文,就不可能说出写它的人在想什么。他们可能不知道数组是如何工作的。我以为我已经回答过了。如果当前目录中恰好有一个名为 THIS* 的文件,则会出现非法名称错误,否则在 Bash 中,在指定索引的同时声明一个空数组只会创建数组并忽略指定的索引,在 * 的情况下并且非关联索引数组无效。无论如何,这不是任何人都想要的。
猜你喜欢
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多