Fish Shell - 値の配列を確認するスイッチステートメントを生成するための構文

Fish Shell - 値の配列を確認するスイッチステートメントを生成するための構文

私はRBENVコードベースに取り組んでいて発見しました。rbenv-initファイルライン116、ステートメントを含む関数を作成しますswitch。私の前提は、変数の値がcommand(複数の)変数の値配列メンバーの1つであることを確認することですcommands。その場合は、スイッチステートメントの分岐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私はスクリプトに提供する2つのパラメータを含み、評価される配列を期待していました。私の構文はソースコードの117行の構文と一致します。barbazcase ${commands[*]}

私がスクリプトを実行しているシェルはzsh v5.8.1ですが、私のshebangは特に「fish」シェルを参照しているので、シェルは重要ではないと思います。私はfish v3.5.1をインストールしました。

ベストアンサー1

バッシュコードは次のとおりです。

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

rbenv-commands --shこれはSplit + globが適用され、結果の単語が要素に割り当てられた出力です。$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。ほとんどの$ものはプレフィックスと見なされますが、そうでは\ありません${commands[*]}(とにかくフィッシュ構文ではなくKornシェル構文です)。 bashはそれを$commands最初の文字に$IFS関連付けられた配列要素に展開します(デフォルトは空白)。

したがって、このコマンドで生成されたフィッシュコードは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

文字列がリストにあるかどうかを確認するには、fishbuitincontainsを使用できます。

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'に似ています。)[[ $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] ))

おすすめ記事