1

I want to check if the given variable is set with the -v check. I'm struggling to understand where the error is coming from. Having the following script in a file var-test.sh:

MY_VAR="test"

if [ -v MY_VAR ]; then
  echo "MY_VAR set to $MY_VAR"
else
  echo "MY_VAR not set"
fi

when I run it: ./var-test.sh I get the following output:

./var-test.sh: line 3: [: -v: unary operator expected
MY_VAR not set

But when I invoke the following command in the shell prompt:

MY_VAR="test"; if [ -v MY_VAR ]; then echo "MY_VAR set to $MY_VAR"; else; echo "MY_VAR not set"; fi

the shell doesn't complain about the -v operator and outputs "MY_VAR set to test" as expected. What gives? Am I missing something obvious?

I thought it's because of using single brackets. When I switch to using double brackets:

MY_VAR="test"

if [[ -v MY_VAR ]]; then
  echo "MY_VAR set to $MY_VAR"
else
  echo "MY_VAR not set"
fi

I get the following error:

./var-test.sh: line 3: conditional binary operator expected
./var-test.sh: line 3: syntax error near `MY_VAR'
./var-test.sh: line 3: `if [[ -v MY_VAR ]]; then'

The output of zsh --version:

zsh 5.7.1 (x86_64-apple-darwin19.0)
mjarosie
  • 113
  • 5
  • 1
    What does `man zsh` say? If that manpage just slightly resembles what `man bash` contains - then you might wish to use the (less -command) `/`-key to enter something to search for, maybe `VARIABLE EXPRESSION` for example. – Hannu Jan 11 '21 at 17:14
  • You seem to miss a shebang (`#!/bin/zsh`) line in your script, so maybe it's not executed with zsh?! – mpy Jan 11 '21 at 17:50

1 Answers1

2

Explicitly choose an interpreter by specifying a shebang. There is no shebang in your current script. When called from zsh such script runs with sh. Apparently whatever provides sh in your system does not support [ -v …. Zsh supports this, Bash supports this, other shells may not.

It seems you want to use Zsh, so the shebang should be #!/bin/zsh or similar. It must be the very first line of the script.

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
  • Thanks, it worked! Why does it work though if I use `#!/bin/zsh` shebang, but it doesn't if I use `#!/usr/bin/env bash` shebang? When I add the following line: `echo $($SHELL --version)`, it gives exactly the same output in both cases (`zsh 5.7.1 (x86_64-apple-darwin19.0)`), but the `bash` version still fails on the `-v` check. – mjarosie Jan 12 '21 at 08:55
  • OK I've got it. Echoing these two variables in the script: `$BASH_VERSION`, `$ZSH_VERSION` produces the following output: - in case of `#!/usr/bin/env bash`: `$BASH_VERSION` is `3.2.57(1)-release` (`$ZSH_VERSION` is empty) - in case of `#!/bin/zsh`: `$ZSH_VERSION` is `5.7.1` (`$BASH_VERSION` is empty) – mjarosie Jan 12 '21 at 09:15
  • 1
    @mjarosie `$SHELL` is not the shell you're in. [It's your login shell](https://unix.stackexchange.com/q/277944/108618). That's why the same output (and [`echo` here is weird](https://superuser.com/q/1352850/432690)). Since Zsh mentions `apple-darwin` then [maybe your Bash is old](https://apple.stackexchange.com/a/197172). It seems [you need Bash 4.2](https://unix.stackexchange.com/q/56837/108618). – Kamil Maciorowski Jan 12 '21 at 09:17
  • Thanks Kamil, there's obviously a lot for me to catch up in terms of knowledge about differences between shells and how it's all set up. Thanks for all the links as well! – mjarosie Jan 12 '21 at 09:56