鱼shell。如何检查变量是否为 set/empty?

fish shell. How to check if a variable is set/empty?

我该如何做

set variable (some_command_that_may_return_a_string)
if [ variable is set ]
    do_something

反之如何检查变量是否为空?

  • set -q var(注意缺少的“$” - 这使用变量 name)可用于检查是否已设置变量.

  • set -q var[1]可用于检查变量的第一个元素是否已赋值(即是否为非空列表)。

  • test -n "$var" [fn0](或[ -n "$var" ])可用于检查变量是否扩展为非空字符串(而test -z是inverse - 如果为空则为真)。

这些将 true/false 在略有不同的情况下。

当根本没有执行过set var时(也没有从父进程继承),set -q varset -q var[1]test -n "$var"将为false , test -z "$var" 将为真。

当完成类似 set var 的操作时(没有任何附加参数),set -q var 将为真,set -q var[1] 将为假。

完成类似 set var "" 的操作后,两个 set 版本都为真。

当像 set var "somestring"(甚至 set var "" "" [fn1])这样的事情完成后,sets 将为真而 test -z "$var" 将为假。


[fn0]:您从不想在不引用变量的情况下使用test(或[)。一个特别令人震惊的例子是 test -n $var 将 return 为真,如果变量包含某些东西并且如果它是 list-empty/unset (根本没有 setset var 没有参数).这是因为 fish 的 test 是 POSIX 之后的少数部分之一,它要求 test 的任何一个参数都为真。它还不能正确处理列表 - test -n $var 如果 var 有多个元素,结果会很奇怪。

[fn1]:这是因为一个列表会通过用spaces连接元素扩展为一个字符串,所以由两个空字符串组成的列表将扩展为“” - 一个space.因为那不是空的,test -z returns false.

@faho 提供了一个很棒的答案,但我认为如果有代码示例会更容易。

function if-test-no-arg
  set var

  if set -q var
    # true
  end

  if set -q var[1]
    # false
  end

  # Always put quotation marks
  if test -n "$var"
    # false
  end

  if test -z "$var"
    # true
  end
end

function if-test-empty-arg
  set var ""

  if set -q var
    # true
  end

  if set -q var[1]
    # true
  end

  if test -n "$var"
    # false
  end

  if test -z "$var"
    # true
  end
end

function if-test-valid-arg
  set var "hello"

  if set -q var
    # true
  end

  if set -q var[1]
    # true
  end

  if test -n "$var"
    # true
  end

  if test -z "$var"
    # false
  end
end

function if-test-no-set
  if set -q var
    # false
  end

  if set -q var[1]
    # false
  end

  if test -n "$var"
    # false
  end

  if test -z "$var"
    # true
  end
end