• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 318
  • Last Modified:

script

I am trying to backup my system..
I started out by trying to write a script like this:

***
#!/bin/sh

DIR_LIST=`cat /etc/backup.list`
LAST_BU_FILENAME=/etc/.backupfull
FILENAME=`date +%Y%m%d.incr.tgz`
PATHNAME=/home/backup/

find $DIR_LIST -newer $LAST_BU_FILENAME -type f -print > /tmp/filez.list

sed 's/ /\\ /g' /tmp/filez.list >/tmp/filez2.list
LIST=`cat /tmp/filez2.list`

#create the initial tar file.. then we'll append to this
tar cvf fred.tar /tmp/filez2.list

for FILETOARCHIVE in $LIST
do

tar rvf fred.tar $FILETOARCHIVE

done

***

This would work if it wasn't for windows weenies. Windows weenies use my linux system as a file server and hence have whitespace in their files (and directories)

But it isn't the tarring that's the problem since i can do this:

tar rvf fred.tar /home/fred/hello\ world/smeg.doc

and it works no problems..
so my problem is in the for loop declaration
it is giving the wrong names to the tar line

hence i need a way to send a complete line (spaces or no spaces) from $LIST to the for expression without it thinking I am specifying a new variable because of the space

Let me try and explain a bit better:

the filez2.list may look like this:
/home/tig/rhosts
/home/tig/hello\ world.doc

the for loop does this
sends /home/tig/rhosts to tar
sends /home/tig/hello to tar
sends world.doc to tar

which is wrong!
(i'm pretty sure what i say is correct)

the "for" expression (as soon as it hits a space) executes the loop.

basically what i need is this:
some way to do a find on my system for updated files (as above) and direct that output into tar

can i do something like this:

find $DIR_LIST -newer $LAST_BU_FILENAME -type f -print | tar rvf fred.tar -

??????

how can this problem be solved?

or can i somehow work around the for loop problem..
0
wehttam
Asked:
wehttam
  • 3
  • 3
  • 3
1 Solution
 
ahoffmannCommented:
sed 's/ /</g' /tmp/filez.list >/tmp/filez2.list

for FILETOARCHIVE in `cat /tmp/filez2.lst`; do
   filename="`echo "\"$FILETOARCHIVE"\" | sed -e 's/</\ /g'`"
   tar rvf fred.tar $FILETOARCHIVE
done

0
 
zblaxellCommented:
Wow...not only is it complicated, it's beyond repair...

    #!/bin/sh

    DIR_LIST=`cat /etc/backup.list`
    LAST_BU_FILENAME=/etc/.backupfull
    FILENAME=`date +%Y%m%d.incr.tgz`
    PATHNAME=/home/backup/

    echo -ne '/tmp/filez2.list\000' > /tmp/filez2.list
    find $DIR_LIST -newer $LAST_BU_FILENAME -type f -print0 >> /tmp/filez2.list
    cpio -ov0Htar < /tmp/filez2.list > fred.tar

This problem is much more appropriately solved in perl than a shell script.  Shell scripts have chronic character quoting problems (not to mention security problems) that make doing anything like this with a for loop in a shell a guaranteed disaster.  In addition to handling spaces correctly (which you aren't doing...you need "$VARIABLE" instead of $VARIABLE everywhere in your shell script), you have to handle newlines and \377's if you want to handle the entire Unix filename character set.
0
 
wehttamAuthor Commented:
Ahoffmann,
you solution failed to work. It did not successfully pick up files/directories with spaces.
I appreciate your help..

zblaxell,
your solution worked correctly.
please answer to receive your points


0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
ahoffmannCommented:
as zblaxell said, anything else than [a-zA-Z0-9_+,.-;:_=%@]  in a shell  *may*  be  "a guaranteed disaster"  but *must not* be.
Probaly my solution just misses the quotes in the tar command
(as zblaxell said), sorry.
I also thaught of posting a solution which did tar all files at once, and not one by one (see zblaxell's comment), 'cause there aren't any prblems with any character in filenames as long as the name is not parsed by the shell itself.
0
 
wehttamAuthor Commented:
>I also thaught of posting a solution which did tar all files at once, and not one by one
>(see zblaxell's comment), 'cause there aren't any prblems with any character in
>filenames as long as the name is not parsed by the shell itself.

I am aware that tar won't have a problem with this as initially i was using tar with the -N option to recursively pick up any new files in any directory. This worked fine except for the fact that tar's -N option is a very poor implementation since it seems to focus on directory dates instead of individual file dates. Hence I needed to use the 'find' command and direct it into tar. But this is not an option for tar if the file/directory has whitespace.. although later on i discovered tar can grab whitespace.. but the for loop was causing the problem.
But i explained all this in my question above.

Anyways, I appreciate your help.
0
 
zblaxellCommented:
"please answer to receive your points"

OK, here it is...
0
 
ahoffmannCommented:
ok, how about this (didn't chech tar options):

find $DIR_LIST -newer $LAST_BU_FILENAME -type f -exec tar rvf fred.tar {} \;

(it's a single line, probably wrapped by e-e).
0
 
zblaxellCommented:
Or:

find $DIR_LIST -newer $LAST_BU_FILENAME -type f -print0 | xargs -0 tar rvf fred.tar
0
 
wehttamAuthor Commented:
thanks guys
i'll try em out

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 3
  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now