1

I'm trying to declare and append to an array in a bash script, after searching i resulted in this code.

list=()
list+="string"

But when i echo this out it results in nothing. I have also tried appending to the array like this

list[$[${#list[@]}+1]]="string"

I don't understand why this is not working, anyone have any suggestions?


EDIT: The problem is list is appended to inside a while loop.

list=()

git ls-remote origin 'refs/heads/*' | while read sha ref; do
    list[${#list[@]}+1]="$ref"
done

declare -p list

see stackoverflow.com/q/16854280/1126841

A.Jac
  • 1,443
  • 3
  • 17
  • 24
  • How are you echo-ing it out? – Inian Feb 03 '17 at 11:43
  • I have tried ' echo "${list}" ', ' echo "$list" ' and ' echo $list ' – A.Jac Feb 03 '17 at 11:47
  • Can you try `echo "${list[0]}"` – Inian Feb 03 '17 at 11:48
  • Still returns nothing – A.Jac Feb 03 '17 at 11:50
  • 1
    try list+=('foo') – clearlight Feb 03 '17 at 12:01
  • The list is still empty after list+=('foo') – A.Jac Feb 03 '17 at 12:05
  • @A.Jac Cannot reproduce your first error; `$list` and `${list[0]}` are effectively equivalent. `list+="string"` won't add `string` to the array, but it will append `string` to the end of the first element of the array (creating said element if necessary). – chepner Feb 03 '17 at 12:10
  • 1
    `$[...]` is obsolete (use `$((...))` instead) and unnecessary; the index of a regular array is automatically evaluated in an arithmetic context, so `list[${#list[@]}+1]="string"` would be sufficient. – chepner Feb 03 '17 at 12:11
  • By the way, you can see what bash thinks about that variable by running `declare -p list`. If it is an array will be printed like `declare -a list=.` – George Vasiliou Feb 03 '17 at 12:14
  • ok, so i tried `list[${#list[@]}+1]="string"` and `declare -p list` it results in `declare -a list='()'` – A.Jac Feb 03 '17 at 12:22
  • Not sure what is going on: I get `declare -a list='([1]="string")'`. – chepner Feb 03 '17 at 12:30
  • The only thing i can think of is incompatibility between bash and zsh (which im using). But shouldn't be an issue since i have shebang added – A.Jac Feb 03 '17 at 12:38
  • The problem seems to be my lack of shell knowledge, since the appending is happening inside a while loop it is not remembered after loop is done, need to find a workaround for it. – A.Jac Feb 03 '17 at 12:57
  • The loop wouldn't happen to be in a pipeline, would it? This is a *completely* different problem, and this is why your question needs to provide an example that actually reproduces your problem. – chepner Feb 03 '17 at 13:34
  • 1
    See http://stackoverflow.com/q/16854280/1126841. – chepner Feb 03 '17 at 13:39

2 Answers2

7

You can append new string to your array like this:

#!/bin/bash

mylist=("number one")

#append "number two" to array    
mylist=("${mylist[@]}" "number two")

# print each string in a loop
for mystr in "${mylist[@]}"; do echo "$mystr"; done

For more information you can check http://wiki.bash-hackers.org/syntax/arrays

chepner
  • 497,756
  • 71
  • 530
  • 681
Ali Okan Yüksel
  • 338
  • 1
  • 13
  • The OP is already using the correct operator to append to an array; this won't make a difference. – chepner Feb 03 '17 at 13:35
1

Ali Okan Yüksel has written down an answer for the first method you mentioned about adding items in an array.

list+=( newitem  another_new_item ··· )

The right way of the second method you mentioned is:

list[${#list[@]}]="string"

Assuming that a non-sparse array has N items and because bash array indexes starts from 0, the last item in the array is N-1th. Therefore the next item must be added in the N position (${#list[@]}); not necessarily in N+1 as you wrote.

Instead, if a sparse array is used, it is very useful the bash parameter expansion which provides the indexes of the array:

${!list[@]}

For instance,

$ list[0]=3
$ list[12]=32
$ echo ${#list[@]}
2
$ echo ${!list[@]}
0 12
Jdamian
  • 3,015
  • 2
  • 17
  • 22