kjr1995
kjr1995

Reputation: 420

Linux bash script to copy directory and sub directories

I want to copy all the files and sub directories from a directory to a different directory. However I only want to copy them if they are not already in the destination directory or if the timestamp on the source directory file is newer than the timestamp on the destination directory. I am having troubles getting into all of the sub directories. I am able to get down one level but not the next. For example, with directory /a/b/c, I am able to get to sub directory b but not to c. The only way I could see doing this was with a recursive function. My code is below.

#!/bin/bash


SOURCEDIR=/home/kyle/Smaug/csis252

DESTDIR=/home/kyle/Desktop/csis252

copy() {
    local DIRECTORY=$1
    for FILE in `ls $DIRECTORY`
    do
        if [ -f $DIRECTORY/$FILE ]
        then
            echo $FILE file
            cp $DIRECTORY/$FILE $DESTDIR/$DIRECTORY/$FILE
        fi
        if [ -d $FILE ]
        then
            echo $FILE directory
            mkdir $DESTDIR/$DIRECTORY/$FILE
            copy $DIRECTORY/$FILE
        fi
        done
}


cd $SOURCEDIR

copy .

I forgot the $DIRECTORY in the second if statement. I feel stupid now but sometimes it just takes someone else to read through to find stuff like this. I did not use the cp -r $SOURCEDIR $DESTDIR because this would copy everything and sometimes I do not want that. I tried the cp -ur $SOURCEDIR $DESTDIR but it would only copy new stuff over, not update the existing stuff. The final version of my code is below.

#!/bin/bash

SOURCEDIR=/home/kyle/Smaug/csis252

DESTDIR=/home/kyle/Desktop/csis252

copy() {
    local DIRECTORY=$1
    for FILE in `ls $DIRECTORY`
    do
        if [ ! -f $DESTDIR/$DIRECTORY/$FILE ] && [ ! -d $DESTDIR/$DIRECTORY/$FILE ]
        then
        if [ -f $DIRECTORY/$FILE ]
        then
            echo "$DIRECTORY/$FILE copied"
            cp $DIRECTORY/$FILE $DESTDIR/$DIRECTORY/$FILE
        fi
        if [ -d $DIRECTORY/$FILE ]
        then
            echo "$DIRECTORY/$FILE directory made"
            mkdir $DESTDIR/$DIRECTORY/$FILE
            copy $DIRECTORY/$FILE
        fi
    else
        if [ $DESTDIR/$DIRECTORY/$FILE -nt $DIRECTORY/$FILE ] && [ ! -d $DIRECTORY/$FILE ]
        then
            cp $DIRECTORY/$FILE $DESTDIR/$DIRECTORY/$FILE
            echo "$DIRECTORY/$FILE updated"
        fi
    fi
    done
}

cd $SOURCEDIR
copy .

Upvotes: 0

Views: 4528

Answers (2)

nu11p01n73R
nu11p01n73R

Reputation: 26687

Simpler would be

cp -ur $SOURCEDIR $DESTDIR

-r recursivly copies folders and subfolders

-u updates, copies only when the source is newer

Upvotes: 3

user743382
user743382

Reputation:

if [ -f $DIRECTORY/$FILE ]

...

if [ -d $FILE ]

You forgot $DIRECTORY/ in your -d check. This isn't a problem for the top-level directories, because when DIRECTORY is ., [ -d dir ] and [ -d ./dir ] will always give the same result, but for subdirectories it does matter.

Note: you may want to look at pre-written programs that do this. cp (at least the GNU version) or rsync can probably avoid the need for any custom script, and also handle special files (special file name characters, or special file types) better than any script will.

Upvotes: 1

Related Questions