Fish shell - 用於創建檢查值數組的 switch 語句的語法
我正在研究 RBENV 程式碼庫,我看到在文件的第 116 行
rbenv-init
,創建了一個包含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
我期待評估一個包含and
argv
的數組,因為這是我提供給腳本的兩個參數。我的語法與原始碼(即)中第 117 行的語法相匹配。bar``baz``case ${commands[*]}
我在其中執行腳本的外殼是 zsh v5.8.1,但是我的 shebang 專門引用了“魚”外殼,所以我認為我的外殼無關緊要。我已經安裝了魚 v3.5.1,fwiw。
裡面的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 都以 a 為前綴\
,但不是${commands[*]}
(無論如何這是 Korn shell 語法,而不是 fish 語法)。這由 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
要檢查字元串是否在列表中,您可以使用
fish
’scontains
buitin:set list foo bar baz set string foo if contains -- $string $list echo $string is in the list end
(如 zsh
if (( $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
(如
zsh
’sif (( $list[(I)$pattern] ))
)。