14

This is a hack I just discovered:

DEBUG=true
$DEBUG && echo "Hello"

And this just happens to work because true is an actual command which returns 0, and the && operator is happy with that:

» true
» echo $?
0

Is there a non-hackish way of execute a piece of code if a variable is set, to whatever value, except the empty string? Something like this, but as a readable one-liner (like the one above):

myvar="ggg"
if [ "$myvar" != "" ] ; then echo "Hello" ; fi
blueFast
  • 41,341
  • 63
  • 198
  • 344
  • 3
    `[[ -n "$myvar" ]] && echo "Hello"` should work – anubhava Sep 21 '16 at 14:55
  • `[ -z ${myvar+x} ] && echo "Hello"` [see also](https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bashsee) – redneb Sep 21 '16 at 14:56
  • I don't think it is hackish. – hek2mgl Sep 21 '16 at 14:58
  • @hek2mgl: it relies on the shell executing the expansion of a variable as a command, which happens to return a true value. That seems quite hackish. And besides, it does not solve the *whatever value* part ... – blueFast Sep 21 '16 at 15:01
  • 1
    I definitely agree that it's a hack. Personally, I use integer values: `foo=1; ((foo)) && whatever`, or check for empty strings: `[[ $foo ]] && whatever`. – Charles Duffy Sep 21 '16 at 16:05

2 Answers2

20

If you want to use the value:

[[ -n $DEBUG ]] && echo "Hello"

If you want to use the negation of the value:

[[ -z $DEBUG ]] && echo "Hello"

That's I think is the shortest. Note the $ in front of the variable name is required.

run_the_race
  • 1,344
  • 2
  • 36
  • 62
Hasan Baidoun
  • 1,095
  • 9
  • 18
  • 4
    Can you tell me where that syntax comes from? I'd like to be able to document and understand why this works [[ -n $DEBUG ]]. – Lisa Kester Jan 11 '19 at 19:25
  • @LisaKester `man test` lists all the tests (`-n`, `-z`, etc.) that can be applied to an expression in your shell. – mike Jan 26 '23 at 20:31
10

Instead of relying on the value of the variable to have an executable value (and a value that you want to be executed), define a function that simply checks if the value is set.

debug () [[ -v DEBUG ]]

debug && echo "Hello"

If DEBUG is set at all, even to the empty string, debug will succeed and the following command executes.

If DEBUG is not set and you want your script to run the debug commands, simply invoke it as

DEBUG= ./myscript

If DEBUG is set, you can unset it first.

unset DEBUG
./myscript

If the value of DEBUG really matters for whatever reason, then you can just test that it has a non-empty value instead of using -v:

debug () [[ -n $DEBUG ]]

To run your script in debug mode, pick an arbitrary non-empty value

DEBUG=1 ./myscript

To run your script in "real" mode even if DEBUG is current set in your environment, use

DEBUG= ./myscript
chepner
  • 497,756
  • 71
  • 530
  • 681