Home > Back-end >  Is there a way to access an array value by index x in bash?
Is there a way to access an array value by index x in bash?

Time:03-18

I'm trying to create a relatively basic bash script that creates a folder named with a timestamp, adds the name into an array, and then recall that name a few loops later so that the folder can be deleted and replaced with another. The idea is that the script will run every X often, make a backup of something in a timestamped folder, and eventually start clearing out the oldest backup once it reaches a predetermined limit.

The way I'm currently trying to do this is:

intervl=2
blimit=10 #Max number of backups to keep before removing oldest at next run
spath="/example/example/example"
opath="/otherexample/otherexample/otherexample"

limitcounter=0
timearray=() #Array for storing the folder names so they can be recalled and overwritten

while [ "$limitcounter" -lt "$blimit" ]; do
  rm -r $opath/$timearray[$limitcounter] 
  timestamp=$(date  %Y-%m-%d_%H-%M-%S) #Generate a new timestamp
  timearray[$limitcounter]=$timestamp #Add new timestamp to the array at position limitcounter
  cp -r $spath $opath/$timestamp #Copy the folder and files from save location to folder at position opath/timestamp 
  ((limitcounter =1)) #Incrementing limitcounter
  sleep $intervl #Wait 1 interval before continuing
done

I left it out, but assume there is a larger while loop that eventually resets $limitcounter to 0 and that is working properly.

CodePudding user response:

The immediate problem is that you need to use curly braces when getting an element from the array; that is, use ${array[index]} instead of just $array[index]. Note that this doesn't apply when assigning to an element; that is, array[index]=value is correct, but {array[index]}=value will get you an error.

You should also almost always put double-quotes around variable (or array element) expansions, to avoid weird parsing of whitespace or some other characters. With both of these corrections, your rm command should look more like this:

rm -r "$opath/${timearray[$limitcounter]}"

(You could also leave off the $ in $limitcounter, since variables are automatically expanded in arithmetic contexts like the index of a regular array. But that's just a matter of style.)

shellcheck.net is good at spotting common mistakes like these, and I strongly recommend using to sanity-check your scripts.

But I also see what looks like a logic problem in the script: in the beginning, the timearray array will be empty, so in that rm command the ${timearray[$limitcounter]} part will expand to the empty string, and it'll execute the equivalent of rm -r "$opath/" -- that is, it'll delete the entire output directory!

Without knowing the full script, I don't know if this is sufficient to fix the problem, but the first thing that comes to mind is to use if [[ -n "${timearray[$limitcounter]}" ]] to make sure the array element is non-blank before running rm based on it.

  •  Tags:  
  • bash
  • Related