Search code examples
shelltestingeval

Weird eval result when using test


Got a variable called a:

unset b
a="b"

Trying to take this statement:

if test -n "$(eval \$${a})"; then echo Y; fi
# Outputs nothing

which works nicely - it evaluates \$${a} to $b, which is empty and doesn't echo.

Trying to convert the above into something similar to this:

eval "if test -n \$${a}; then echo Y; fi"
# Outputs "Y"

which doesn't work - but even weirder:

eval "if test -z \$${a}; then echo Y; fi"
# Outputs "Y"

Why is this? How is the same statement outputting Y for both the above? Can I format the first statement as I've tried to using eval throughout?


Solution

  • eval "if test -n \$${a}; then echo Y; fi"
    

    is the same as following where a is b:

    eval 'if test -n $b; then echo Y; fi'
    

    Since b is unset, and $b is unquoted, it is literally lost after expansion, thus eval evaluates the following:

    if test -n; then echo Y; fi
    

    For -n is not an empty string, test -n evaluates to true and echo Y is executed.