6

I'm trying to assign an array of three values to a variable if it hasn't been assigned yet with the line

: ${SEAFILE_MYSQL_DB_NAMES:=(ccnet-db seafile-db seahub-db)}

Unfortunately, echoing ${SEAFILE_MYSQL_DB_NAMES[@]} results in (ccnet-db seafile-db seahub-db) and ${SEAFILE_MYSQL_DB_NAMES[2]} prints nothing. It seems, the value has been interpreted as a string and not as an array. Is there any way I can make my script assign an array this way?

4
  • 1
    Are you sure this works on your Ubuntu machine? I just tried it on my debian unstable machine with GNU bash, version 4.3.42(1)-release and it did not work the way you said you expect/saw. That all said I'm not sure that I would even expect this to work in the first place. Array assignment isn't the same as the :=/= expansion. Commented Apr 27, 2016 at 16:54
  • @EtanReisner You're right, must have made a mistake when testing it, it behaves the same on the Ubuntu machine. What do you mean exactly with "Array assignment isn't the same as the :=/= expansion"? I would assume that assigning a value in the default value construct acts the same as when simplly assigning it the normal way (i.e. SEAFILE_MYSQL_DB_NAMES=(ccnet-db seafile-db seahub-db) results in an array variable) Commented Apr 27, 2016 at 17:02
  • The := expansion is not the same as a simple assignment. There's no reason to assume that they have to work the same way. Normal array assignment is a specific "compound assignment" nothing says that the := expansion needs to support the same compound assignment. It certainly could work that way but I don't think it is a necessary assumption/extension that it would. Commented Apr 27, 2016 at 17:13
  • There are no array values in bash; x=(1 2 3) is just special syntax for repeated assignments to indexed names, not the assignment of a single special value to the name x. Commented Jan 19, 2023 at 18:18

1 Answer 1

2

How about doing it in several stages? First declare the fallback array, then check if SEAFILE_MYSQL_DB_NAMES is set, and assign if needed.

DBS=(ccnet-db seafile-db seahub-db)
[[ -v SEAFILE_MYSQL_DB_NAMES ]] || read -ra SEAFILE_MYSQL_DB_NAMES <<< ${DBS[@]}

Based on this answer.

Sign up to request clarification or add additional context in comments.

4 Comments

This doesn't work—SEAFILE_MYSQL_DB_NAMES is set to DBS and not to (ccnet-db seafile-db seahub-db).
oops, that still returns a string instead of an array, I've used a different approach now.
Use quotes on variable expansion to prevent word splitting and pathname expansion.
@heemayl, but the array should be split by spaces, no? What do you mean?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.