Fish shell - 用于创建 switch 语句的语法,该语句检查值数组

Fish shell - 用于创建 switch 语句的语法,该语句检查值数组

我正在研究 RBENV 代码库,我发现rbenv-init文件第 116 行,创建一个包含switch语句的函数。我的假设是,我们检查变量的值是否command是(复数)变量中值数组的成员之一commands。如果是,我们执行 switch 语句的分支 1。否则,我们执行分支 2。

我想写一个简单的脚本来检验我的假设,所以我写了以下内容:

#!/usr/bin/env fish

set command "foo"

switch $command
case ${argv[*]} 
  echo "command in args"
case "*" 
  echo "command not found"
end

但是,当我运行此脚本时,出现以下错误:

$ ./foo bar baz

./foo (line 6): ${ is not a valid variable in fish.
case ${argv[*]} 
      ^
warning: Error while reading file ./foo

我原本期望对包含和argv的数组进行求值,因为这是我向脚本提供的两个参数。我的语法与源代码中第 117 行的语法相匹配(即)。barbazcase ${commands[*]}

我执行脚本的 shell 是 zsh v5.8.1,但是我的 shebang 特别引用了“fish”shell,所以我认为我的 shell 并不重要。我安装了fish v3.5.1,fwiw。

答案1

其中的 bash 代码是:

commands=(`rbenv-commands --sh`)

这就是 split+glob 应用于 的输出rbenv-commands --sh,并将生成的单词分配给 的元素$commands bash大批

case "$shell" in
fish )
  cat <<EOS
function rbenv
  set command \$argv[1]
  set -e argv[1]
  switch "\$command"
  case ${commands[*]}
    rbenv "sh-\$command" \$argv|source
  case '*'
    command rbenv "\$command" \$argv
  end
end
EOS
  ;;

cat << EOS...输出一些fish代码,但由于EOS未引用该代码,因此仍会执行扩展(通过 bash)。除非前面有反斜杠,否则$param由 展开bash。您会注意到大多数$s 都以 为前缀\,但不是${commands[*]}(无论如何这是 Korn shell 语法,而不是 Fish 语法)。 bash 将其扩展为$commands与第一个字符$IFS(默认为空格)连接的数组元素。

因此该命令生成的 Fish 代码cat类似于:

function rbenv
  set command $argv[1]
  set -e argv[1]
  switch "$command"
  case elements of the commands bash array
    rbenv "sh-$command" $argv|source
  case '*'
    command rbenv "$command" $argv
  end
end

要检查字符串是否在列表中,您可以使用fish's containsbuitin:

set list foo bar baz
set string foo
if contains -- $string $list
  echo $string is in the list
end

(如 zshif (( $list[(Ie)$string] ))或非空列表if [[ $string = (${(~j[|])list}) ]]

您还可以这样做:

switch $string
  case $list
    echo $string matches at least one of the patterns in the list
end

(除非列表中的任何元素都不包含*?字符,否则这是不一样的)

(这更像是zsh's [[ $string = (${(j[|])~list}) ]](对于非空列表))。

还有:

if string match -q -- $pattern $list > /dev/null
  echo at least one of the elements of the list matches $pattern
end

(比如zshif (( $list[(I)$pattern] ))

相关内容