52

How can I do something like

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

and inversely how do I check if the variable is empty?

Adham Zahran
  • 1,973
  • 2
  • 18
  • 35

3 Answers3

80
  • set -q var (note the missing "$" - this uses the variable name) can be used to check if a variable has been set.

  • set -q var[1] can be used to check whether the first element of a variable has been assigned (i.e. whether it is non-empty as a list).

  • test -n "$var" [fn0] (or [ -n "$var" ]) can be used to check whether a variable expands to a non-empty string (and test -z is the inverse - true if it is empty).

These will be true/false in slightly different circumstances.

When no set var has been performed at all (and it has not been inherited from the parent process), set -q var, set -q var[1] and test -n "$var" will be false, test -z "$var" will be true.

When something like set var has been done (without any additional arguments), set -q var will be true, set -q var[1] will be false.

When something like set var "" has been done, both set versions will be true.

When something like set var "somestring" (or even set var "" "" [fn1]) has been done, the sets will be true and test -z "$var" will be false.


[fn0]: You never want to use test (or [) without quoting the variable. One particularly egregious example is that test -n $var will return true both if the variable contains something and if it is list-empty/unset (no set at all or set var without arguments). This is because fish's test is one of the few parts that follow POSIX, and that demands that test with any one argument be true. Also it does not handle lists properly - test -n $var will have weird results if var has more than one element.

[fn1]: This is because a list will be expanded as a string by joining the elements with spaces, so the list consisting of two empty strings will expand to " " - one space. Since that isn't empty, test -z returns false.

faho
  • 14,470
  • 2
  • 37
  • 47
  • 1
    How does this go into an if statement? – Gringo Suave Aug 23 '20 at 21:47
  • 3
    Like all things in shellscript, `if` and then the thing. So `if set -q var[1]`, `if test -n "$var"` and so on. `if` doesn't take a condition but a command to call, and uses its exit status. – faho Aug 25 '20 at 11:56
  • 1
    I arrived here to learn that, in fish, we need to quote our variables in `test` and `[ ]` expressions. Thank you for this tidbit, which cured my errors. – krry Apr 12 '22 at 05:11
14

@faho provided an awesome answer but I thought it would be easier if there's a code example.

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
Sanghyun Lee
  • 21,644
  • 19
  • 100
  • 126
3

The modern version of fish shell (3.5.1) has string commands.

  • string length --quiet $var checks that the variable is not empty
  • not string length --quiet $var checks that the variable is empty
Valery Viktorovsky
  • 6,487
  • 3
  • 39
  • 47