LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 07-28-2005, 08:10 AM   #1
ldp
Member
 
Registered: Apr 2004
Location: Belgium Antwerpen
Distribution: slackware - knoppix
Posts: 141

Rep: Reputation: 18
Bash 2 dimensional array


Hi, I have this small problem with a bash script:

#!/bin/bash

echo "start full backup"

if [ ! -d /mnt/hdb/bu ]; then
echo "creating new backup folder"
mkdir /mnt/hdb/bu
fi

touch /mnt/hdb/bu/bulogerr.txt

#always make sure that you make a safe copy of the previous full backup
#so you can always fall back on the full bu of last week.

BUFILES="/mnt/hdb/bu/etc_all.tar
/mnt/hdb/bu/var_all.tar
/mnt/hdb/bu/home_all.tar
/mnt/hdb/bu/root_all.tar
/mnt/hdb/bu/apache2_all.tar
/mnt/hdb/bu/mysqldb_all.tar"

for fl in $BUFILES; do
echo -n "compressing previous $fl using gzip... "
if [ -f $fl ]; then
gzip -f -S .gz $fl >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt
if [ "$?" -eq 0 ]; then
rm $fl >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt
echo "sucess"
else
echo "failed: could not gzip $fl"
fi
else
echo "failed: $fl could not be found"
fi
done

FILES="/etc /mnt/hdb/bu/etc_all.tar
/var /mnt/hdb/bu/var_all.tar
/home /mnt/hdb/bu/home_all.tar
/root /mnt/hdb/bu/root_all.tar
/usr/local/apache2 /mnt/hdb/bu/apache2_all.tar
/usr/local/mysql/var /mnt/hdb/bu/mysqldb_all.tar"

for fl in $FILES; do
set -- $fl
echo -n "backup $1 with tar... "
tar cvf $2 $1 >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt
if [ "$?" -eq 0 ]; then
echo "sucess"
else
echo "failed: see bulogerr.txt for details"
fi
done

echo "backup done"

exit 0


the first part where I compress the .tar files works out just fine but the second part where I create the .tar files doesn't work at all.
I get the following output:

start full backup
backup /etc with tar... failed: see bulogerr.txt for details
backup /mnt/hdb/bu/etc_all.tar with tar... failed: see bulogerr.txt for details
backup /var with tar... failed: see bulogerr.txt for details
backup /mnt/hdb/bu/var_all.tar with tar... failed: see bulogerr.txt for details
backup /home with tar... failed: see bulogerr.txt for details
backup /mnt/hdb/bu/home_all.tar with tar... failed: see bulogerr.txt for details
backup /root with tar... failed: see bulogerr.txt for details
backup /mnt/hdb/bu/root_all.tar with tar... failed: see bulogerr.txt for details
backup /usr/local/apache2 with tar... failed: see bulogerr.txt for details
backup /mnt/hdb/bu/apache2_all.tar with tar... failed: see bulogerr.txt for details
backup /usr/local/mysql/var with tar... failed: see bulogerr.txt for details
backup /mnt/hdb/bu/mysqldb_all.tar with tar... failed: see bulogerr.txt for details
backup done

=> Instead of executing the "tar cvf $2 $1 >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt" command with both the variables, it looks like he tries it with each one at a time:

I want: tar cvf /mnt/hdb/bu/etc_all.tar /etc >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt

but all I seem to get is: tar cvf /etc >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt or: tar cvf /mnt/hdb/bu/etc_all.tar >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt

I was looking for 2dim arrays but they look quite impossible in bash...

Thanks if someone can help me out or point me in the right direction here.

kind regards,
Lieven
 
Old 07-28-2005, 09:26 AM   #2
ldp
Member
 
Registered: Apr 2004
Location: Belgium Antwerpen
Distribution: slackware - knoppix
Posts: 141

Original Poster
Rep: Reputation: 18
Ok, just made two one dimensional arrays with the same index, made it look like:

X=6

f[1]=/mnt/hdb/bu/etc_all.tar
f[2]=/mnt/hdb/bu/var_all.tar
f[3]=/mnt/hdb/bu/home_all.tar
f[4]=/mnt/hdb/bu/root_all.tar
f[5]=/mnt/hdb/bu/apache2_all.tar
f[6]=/mnt/hdb/bu/mysqldb_all.tar

d[1]=/etc
d[2]=/var
d[3]=/home
d[4]=/root
d[5]=/usr/local/apache2
d[6]=/usr/local/mysql/var

i=0
while [ "$i" -lt "$X" ]
do
let "i++"
echo "file: ${f[$i]} directory: ${d[$i]}"
done


=> output looks ok now.
Why-o-why are there no multi-dimensional arrays in bash?
 
Old 07-28-2005, 10:06 AM   #3
Quigi
Member
 
Registered: Mar 2003
Location: Cambridge, MA, USA
Distribution: Ubuntu (Dapper and Heron)
Posts: 377

Rep: Reputation: 31
You could simplify the problem by creating a map for the 6,
* etc -> /etc
* var -> /var
...
* mysql -> /usr/local/mysql/var
You could just set "etc=/etc" and so on, and get the directory using
Code:
eval dir=$`echo $fl`
Or do the same using symlinks, or maybe bash has some associative arrays.
And then you could have a 1d loop over "etc var home root apache2 mysqldb".

But you asked for a bash solution with a 2D array. You can separate the two values that belong together with a comma, and change the following part of your original script:
Code:
FILES="/etc,/mnt/hdb/bu/etc_all.tar
/var,/mnt/hdb/bu/var_all.tar
/home,/mnt/hdb/bu/home_all.tar
/root,/mnt/hdb/bu/root_all.tar
/usr/local/apache2,/mnt/hdb/bu/apache2_all.tar
/usr/local/mysql/var,/mnt/hdb/bu/mysqldb_all.tar"

for fl in $FILES; do
set -- `echo $fl | tr , \ `
echo -n "backup $1 with tar... "
The "tr" command translates the comma, which isn't special to the shell, back to space, which is. Instead of comma you could use any other character that doesn't occur in FILES.
 
Old 07-29-2005, 06:00 AM   #4
ldp
Member
 
Registered: Apr 2004
Location: Belgium Antwerpen
Distribution: slackware - knoppix
Posts: 141

Original Poster
Rep: Reputation: 18
Ok, so I understand that tr can split a variable using a delimiter you can choose freely.

But I still don't understand why simply set -- $fl didn't work.
I tested it on the shell:
var="abc def"
set -- $var
echo $1 #output: abc
echo $2 #output: def

=> why doesn't it work in the loop?

regards,
Lieven
 
Old 07-29-2005, 10:15 AM   #5
Quigi
Member
 
Registered: Mar 2003
Location: Cambridge, MA, USA
Distribution: Ubuntu (Dapper and Heron)
Posts: 377

Rep: Reputation: 31
The command tr "translates", hence the name. E.g., 'tr abc xyz' will replace every occurrence of a with x, of b with y, and of c with z. See 'man tr' for more. So tr doesn't officially "split" a variable -- it's bash's choice to take whitespace as separator (but not, e.g., comma, slash, letters).

The original loop didn't do what you expected because the list $FILES had 12 words, each of which was assigned to fl, one at a time. Both space and newline are whitespace, and equally separate words. By using commas instead of spaces, I changed that to 6 words.

That said, my preferred solution would still avoid 2D arrays:
Code:
etc=/etc
var=/var
home=/home
root=/root
apache2=/usr/local/apache2
mysqldb=/usr/local/mysql/var

for f in etc var home root apache2 mysqldb; do
  eval dir=$`echo $f`
  echo -n "backup $dir with tar... "
  tar cvf /mnt/hdb/bu/${f}_all.tar $dir >/dev/null 2>>/mnt/hdb/bu/bulogerr.txt
  if [ "$?" -eq 0 ]; then
    echo "sucess"
  else
    echo "failed: see bulogerr.txt for details"
  fi
done
 
Old 07-29-2005, 11:29 AM   #6
ldp
Member
 
Registered: Apr 2004
Location: Belgium Antwerpen
Distribution: slackware - knoppix
Posts: 141

Original Poster
Rep: Reputation: 18
Thanks for the explanation.
Altough I'm sure that the solution I tried at first works (2d table), yours looks more elegant.
kind regards,
Lieven
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
building a three dimensional array in vb6 mrobertson Programming 0 08-18-2005 09:12 AM
bash: put output from `ls` into an array samel_tvom Programming 18 07-31-2005 12:55 AM
memory managment problem; higher dimensional array doesn't delete qanopus Programming 5 06-15-2005 04:18 PM
3 dimensional array help leeach Programming 11 06-15-2005 10:46 AM
array in bin/bash how to x2000koh Programming 12 05-09-2003 04:51 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 05:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration