在Fish Shell中,如何设置具有默认回退的变量?

8
我正在寻找与以下bash语法等效的fish shell语法:
local datafile="${_Z_DATA:-$HOME/.z}"

即定义一个本地变量,如果定义了$_Z_DATA,则该变量将取其值,否则将取$HOME/.z的值。

本地变量不是环境变量。 "环境"变量是导出的变量,可以被甚至不是当前shell的fork()子进程继承。如果您不使用declare -xset -aexport,并且没有已经标记为相同名称的导出内容,则变量只是常规shell变量,而不是环境变量。 - Charles Duffy
3个回答

9
据我所知,没有针对此的语法;你需要像这样做:
set datafile "$_Z_DATA"
test -z "$datafile"; and set datafile "$HOME/.z"

或者

if set -q _Z_DATA; and test -n _Z_DATA
  set datafile "$_Z_DATA"
else
  set datafile "$HOME/.z"
fi

bash 不同,函数内定义的变量自动成为该函数的本地变量,因此不需要等价于 local 的语句。(这个回答的早期版本使用 -l 选项来将变量局部化,但这会使它成为 set 命令所在的任何块的本地变量。)


我已经尝试了第二种if else方法,但不幸的是,变量在退出if块时就超出了作用域(尽管第二种方法运行良好)。 - Nicolas C
去掉 -l 以使变量具有函数作用域。 - ridiculous_fish

4
我会将此写为:

我会这样写:

set -q _Z_DATA; or set _Z_DATA $HOME/.z

在 Fish 3.0+ 版本中,您可以编写以下内容:
set -q _Z_DATA || set _Z_DATA $HOME/.z

如果您经常这样做,您可以定义一个函数:
function defaultset --no-scope-shadowing
    set -q $argv[1] || set $argv[1] $argv[2..-1]
end

# example usage
defaultset _Z_DATA $HOME/.z 

1
原始的bash不会设置_Z_DATA的值;它使用一个预先存在的值来设置datafile,或者如果_ZDATA为空或未定义,则使用$HOME/.z - chepner

3

我并不是一个鱼类专家,但我写了一个辅助函数:

function default
  for val in $argv
    if test "$val" != ""
      echo $val
      break
    end
  end
end

该函数回显第一个非空值(该函数也适用于数字和字符串)。
~> set baz baz
~> default $foo $bar $baz $bat
baz
~> set bar bar
~> default $foo $bar $baz $bat
bar

为在您的脚本中使用,您可以使用括号语法调用该函数:
~> set myfoo (default $foo "default")
~> echo $myfoo
default
~> set foo "the real foo"
~> set myfoo (default $foo "default")
~> echo $myfoo
the real foo

回到您具体的示例:

set datafile (default "$Z_DATA" "$HOME/.z")

这正是我想要的,保持 n-args 比扩展 if 条件、其他命令调用或纯手动工作更简单,而且它甚至还是自动的!虽然我可能会使用 if test -n "$value" - Pysis

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