0

I am reading some bash code and I can't figure out what the "+x" modifier does in the if condition below.

I have read the doc about parameter expansion and about if [-z ..] but this +x perplexes me. In fact, there isn't a single occurrence of "+x" in the whole bash manual (pdf)...

The code is supposed to check if the PASS environment variable is empty. If it is, it sets it to a random password.

if [ -z "${PASS+x}" ] ; then 
             PASS=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
             echo "Password set to: $PASS"
         fi;
asachet
  • 6,620
  • 2
  • 30
  • 74
  • The `x` is just a placeholder; any other non-empty string would work just as well. The `+` is what you'll find in the manual. – Charles Duffy Mar 17 '22 at 17:52
  • See https://wiki.bash-hackers.org/syntax/pe – Charles Duffy Mar 17 '22 at 17:53
  • BTW, the syntax is completely useless here. There were ancient buggy 1970s shells where this idiom was needed, but it serves no purpose in modern ones. I would just use `[ -z "$pass" ]` (all-uppercase variable names are in reserved space and should not be put to application-defined purposes -- see the naming conventions in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html, keeping in mind that shell variables and environment variables share a namespace: Setting a regular shell variable overwrites any like-named environment variable). – Charles Duffy Mar 17 '22 at 17:54
  • ...well, useless unless you want explicitly-set-to-an-empty-string to be honored as "yes, I really want an empty string as my password". That's arguably a valid use case. (Try this: `empty_var=''; unset unset_var 2>/dev/null; echo "${empty_var+1} ${empty_var:+2} ${unset_var+3} ${unset_var:+4}"` to compare the four cases). – Charles Duffy Mar 17 '22 at 17:58
  • @CharlesDuffy Thank you! In summary, `${param+word}` and `${param:+word}` are the same thing. Weirdly, that `+` syntax isn't listed in any of the manuals I consulted or linked above! They only ever talk about `parameter:+word`, with a colon. – asachet Mar 18 '22 at 10:02
  • The meaning of the optional colon is discussed nearby in the docs, but you're correct that both variants aren't listed as separate constructs; one has to read the surrounding text to find the description of how to derive the meaning of the colon-free variants. – Charles Duffy Mar 18 '22 at 14:48
  • I wouldn't agree with the summary that they're "the same thing" -- the difference is whether the empty and unset cases are treated as identical, which the line of code I gave earlier demonstrates (`+` treats set-to-empty as set; `:+` treats set-to-empty as unset). – Charles Duffy Mar 18 '22 at 14:49
  • 1
    You're right - and indeed I should have read the doc more carefully. I was looking for the meaning of "+" when in fact the key was the absence of a colon. The doc agrees with you of course: "When not performing substring expansion, using the form described below (e.g., ‘:-’), Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence." – asachet Mar 20 '22 at 00:45

0 Answers0