0

I have some code that looks like this:

 ################### - Let's call this section 1 if [ -n "$STUFF_JAVA" ]; then __LAUNCHER="$STUFF_JAVA" else __LAUNCHER="java" fi ################### - Let's call this section 2 if [ -n "$JAVA_HOME" ]; then # # echo "DEBUG: Using JAVA_HOME" _STUFF_JAVA_HOME="$JAVA_HOME" _STUFF_JAVA="$_STUFF_JAVA_HOME"/bin/$__LAUNCHER else echo "testing" fi ############## - Let's call this section 3 _STUFF_JAVA_HOME="$JAVA_HOME" _STUFF_JAVA="$_STUFF_JAVA_HOME"/bin/$__LAUNCHER ############## 

I don't understand why section 2 has issues setting the _STUFF_JAVA_HOME variable but section 3 does not? Do I need to use curly brackets or parenthesis somewhere?

I want my code to set the following variables:

_STUFF_JAVA_HOME _STUFF_JAVA 

I don't understand why it gets set in section 3 but not section 2.

For some reason, in section 2, it's not able to pick up the variable to determine the length...

Is there something I am missing?

(I am inexperienced with shell script. I am reading a book and have literally finished chapter 1.)

3
  • What do you mean by "has issues"? Your section2 sets _STUFF_JAVA_HOME and then uses the uninitialized _PENTAHO_JAVA_HOME. How is that supposed to work?CommentedJun 12, 2023 at 20:04
  • 1
    You should try yourself, you still didn't explain what your code is supposed to do, and how it fails.CommentedJun 12, 2023 at 20:18
  • Try echoing every variables after each assignment just to debug.
    – annahri
    CommentedJun 12, 2023 at 22:30

1 Answer 1

0
(base) jj@tb-jj:/$ ################### - Let's call this section 1 if [ -n "$STUFF_JAVA" ]; then __LAUNCHER="$STUFF_JAVA" else __LAUNCHER="java" fi ################### - Let's call this section 2 if [ -n "$JAVA_HOME" ]; then # # echo "DEBUG: Using JAVA_HOME" _STUFF_JAVA_HOME="$JAVA_HOME" _STUFF_JAVA="$_STUFF_JAVA_HOME"/bin/$__LAUNCHER else echo "testing" fi (base) jj@tb-jj:/$ echo "$_STUFF_JAVA" ./Some/Path/bin/java (base) jj@tb-jj:/$ echo "$_STUFF_JAVA_HOME" ./Some/Path 

It appears to be working fine. Can you be more specific with what the undesirable behavior actually IS? Also, you DO have a JAVA_HOME variable set, yes?

Also, I observe you've omitted the _ from _STUFF_JAVA in the Section 1 test and variable assignment. Is this intentional?

And, finally, a -n comparison is verifying that a variable is not null (or, more precisely, that it is a string whose length is -not zero).

This is distinct from a -z comparison (which is testing for a -zero-length string).

Consequently, note that [ -n "$my_var" ] will yield different results than [ -n $my_var ].

(base) jj@tb-jj:/$ [ -n "$BOB" ] && echo 1 # I will produce nothing, because you're expanding $BOB inside a blank \ # string, and then testing if a string is null (it's not). (base) jj@tb-jj:/$ [ -n $BOB ] && echo 1 # I will return 1, because you're now testing on an undeclared variable. 1 

(Note: I manually set my own JAVA_HOME to ./Some/Path before executing the first two sections of your code)

10
  • 2
    "I will return 1, because you're now testing on an undeclared variable." Not quite: when the variable is empty (or unset) but unquoted, the single bracket conditional only sees one argument, "-n". With one argument, the test is true if the argument is a non-empty string. "-n" is a non-empty string, so the result is true and "1" is echoed.CommentedJun 13, 2023 at 12:53
  • I consider this a philosophical point. "If a variable falls in the woods, but no one was around to set it..." or perhaps, "what is the value of an unset variable testing?" -n is testing for the polar opposite of -z: it returns True if the length of string is non-zero (where -z returns true if it IS 0). So let me ask you: given that, why does[ -n $BOB ] test true? What is it that $BOB is handing back that the interpreter views as a non-zero length string? (Note: I don't disagree with you; [ -n ] tests true as well. But if it's looking for a string > 0...? I'm genuinely asking)CommentedJun 14, 2023 at 16:53
  • (@glennjackman I quote the above from all the gnus that's fit to print: gnu.org/software/bash/manual/…. the question I ask at the end there is mine, & directed at you. I'd have thought it would be the opposite, though. My best guess woulda been it's a typing issue. That an unset BOB is being - what? "coerced"? - into a testable value? A boolean? Which is still not a string value. Is it being read as "False"? Is there an stderr value below the surface which is non-zero? Or is the comparator just sloppy and handing back a true by default?CommentedJun 14, 2023 at 17:11
  • @NerdyDeeds, in [ -n $BOB ], if the variable is unset or empty, it disappears during word splitting, and the command that runs is just the same as [ -n ]. That tests the string -n to see if it's empty or not. ([ -n str ] is the same as [ str ]). The test can't tell an unset variable from an empty one.
    – ilkkachu
    CommentedJun 14, 2023 at 17:20
  • @ilkkachu I totally comprehend that is what's happening. What I'm asking is why it is, under the hood. [ -n $VAR ] is supposed to return true if $VAR is a string with a length that is non-zero. An unset variable is not a string. Nor, were it to BE a string, would one suppose it to be a string with something inside it (thus yielding a length other than zero). WHY is $VAR evaluating out to a true when tested using this flag?CommentedJun 14, 2023 at 17:32

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.