Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Need help with a little script
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo
View previous topic :: View next topic  
Author Message
fourhead
l33t
l33t


Joined: 03 Sep 2003
Posts: 875
Location: Cologne, Germany

PostPosted: Sat Oct 29, 2005 3:21 pm    Post subject: Need help with a little script Reply with quote

Hi, I was searching for a way to sync to dirs, and I found a little script for this (rsync won't work for different reasons). The problem is, this script doesn't handle filenames with spaces in them, a file 'name with space.txt' is treating as three files. I believe the problem is with the ls command. Could somebody help me make this script work with such filenames?

Code:

#! /bin/bash

# if [ diff "$1" "$2" ]; then echo falsch; fi
# echo "extended diff"
echo dir: $1 vergleichen mit: $2

for fn in $( ls $1 ); do
# echo Dateiname: "$fn"

if [ -f "$2/$fn" ]; then
diff -q $1/$fn $2/$fn
#echo rv: $?
if (( $? == 0 )); then
#echo touch
touch -r $2/$fn $1/$fn
else
cp -ruv $2/$fn $1/$fn.0
fi

elif [ -d "$2/$fn" ]; then
touch -r $2/$fn $1/$fn
/root/bin/t3 "$1/$fn" "$2/$fn"

# else echo nicht gefunden
fi

done


I'd really appreciate your help, it's a little urgent and I really have no idea of bash scripting.


Tom
Back to top
View user's profile Send private message
truc
Advocate
Advocate


Joined: 25 Jul 2005
Posts: 3199

PostPosted: Sat Oct 29, 2005 3:26 pm    Post subject: Reply with quote

I would write "$something" instead of $something .
Please, let me know if it works :?:
Back to top
View user's profile Send private message
Earthwings
Bodhisattva
Bodhisattva


Joined: 14 Apr 2003
Posts: 7753
Location: Germany

PostPosted: Sat Oct 29, 2005 3:33 pm    Post subject: Reply with quote

Won't work. There are two things you have to keep in mind when dealing with filenames with spaces in bash:

First, when using filenames in a for loop, be careful.
Code:
for file in *.jpg
will work fine as the filename expansion is a bash builtin that handles spaces correctly.
Code:
for file in $(ls *.jpg)
will not work out of the box, as the default IFS contains spaces as well, i.e. bash breaks the filenames returned by the ls command in several strings when they contains spaces. You can set IFS to newline only to make that work.

Second, when passing filenames with spaces to mv/cp etc., quote them as outlined by truc.

There are other utilities than rsync to sync directories. unison for example, or some thing that works remotely over http or ftp IIRC.
_________________
KDE
Back to top
View user's profile Send private message
fourhead
l33t
l33t


Joined: 03 Sep 2003
Posts: 875
Location: Cologne, Germany

PostPosted: Sun Oct 30, 2005 12:42 pm    Post subject: Reply with quote

@earthwings

I understand what you mean, but would there be a way to make

Code:

for fn in $( ls $1 ); do


aware of filenames with spaces in them? Would it help to use ls -l instead, so that every filename is in a single row? I tried rsync, and as I said its only a bad solution for several reasons, and this script would actually do exactly what I need, it would be perfect, it's just this problem with filenames.


Tom
Back to top
View user's profile Send private message
ac_static
n00b
n00b


Joined: 11 Oct 2005
Posts: 45
Location: Ontario, Canada

PostPosted: Sun Oct 30, 2005 12:59 pm    Post subject: Reply with quote

You can always modify how bash determines word separation by doing something like:

Code:

OLDIFS=$IFS
IFS=$'\n' # set IFS to newline only.

# do whatever

IFS=$OLDIFS
#done.
Back to top
View user's profile Send private message
fourhead
l33t
l33t


Joined: 03 Sep 2003
Posts: 875
Location: Cologne, Germany

PostPosted: Mon Oct 31, 2005 11:40 am    Post subject: Reply with quote

Thanks for your tip, but I solved it a little different now. The script looks like this:

Code:

#! /bin/bash

#echo dir: $1 vergleichen mit: $2

cd $1
for fn in *
do

echo Dateiname: $fn
#echo "$2/$fn"
if [ -f "$2/$fn" ]; then
diff -q "$fn" "$2/$fn" > /dev/null
#echo rv: $?
if (( $? == 0 )); then
echo touch
touch -r "$2/$fn" "$fn"
else
echo bkup copy
cp -ruv "$2/$fn" "$fn".0
fi

elif [ -d "$1/$fn" ]; then
touch -r "$2/$fn" "$fn"
/root/bin/t6 "$1/$fn" "$2/$fn"

else
echo nicht gefunden
fi

done


But there's a problem with this script. No matter if the compared files are identical or not ($? is '0' or '1') they're always touched. I've tested it with 10 files, 3 of them different, and on the 7 identical files I see the output 'rv: 0', the 3 changed files cause an output 'rv: 1', which should be correct, but still, only the 'then' argument is executed, not the 'else' (the bkup copy thing). I have no idea why - is there a Bash scipting expert out there ?????


Tom
Back to top
View user's profile Send private message
Cocker68
Apprentice
Apprentice


Joined: 16 Jan 2003
Posts: 227
Location: Germany

PostPosted: Mon Oct 31, 2005 1:52 pm    Post subject: Reply with quote

fourhead wrote:
But there's a problem with this script. No matter if the compared files are identical or not ($? is '0' or '1') they're always touched.
This is because Your successful echo-command sets $? to 0. You have to keep the return code in a separate Variable.

I reworked Your script a little bit:
Code:
#!/bin/bash

SCRIPT=`basename $0`
DIR1="$1"
DIR2="$2"

#echo "$SCRIPT: compare $DIR1 with $DIR2"
[ -d "$DIR1" -a -d "$DIR2" ] || exit 1

# scan DIR1 for files
for NAME in "$DIR1"/*; do
    # we just use the filename here
    NAME=`basename "$NAME"`

    echo "$SCRIPT: Name1: $DIR1/$NAME"
    #echo "$SCRIPT: Name2: $DIR2/$NAME"

    if [ -f "$DIR2/$NAME" ]; then
        # this is a file
        diff -q "$DIR1/$NAME" "$DIR2/$NAME" > /dev/null
        RET=$?
        #echo "$SCRIPT: return value of diff: $RET"
        if [ $RET -eq 0 ]; then
            echo "$SCRIPT: touching the file"
            touch -r "$DIR2/$NAME" "$DIR1/$NAME"
        else
            echo "$SCRIPT: backup-copy of file"
            cp -ruv "$DIR2/$NAME" "$DIR1/${NAME}.0"
        fi
    elif [ -d "$DIR1/$NAME" ]; then
        # this is a directory
        echo "$SCRIPT: touching the directory"
        touch -r "$DIR2/$NAME"  "$DIR1/$NAME"
        /root/bin/t6 "$DIR1/$NAME" "$DIR2/$NAME"
    else
        echo "$SCRIPT: don't know how to handle"
    fi
done

- Cocker :wq
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum