I don't quite see why you can't just use cp -r
or rsync -a
for this, unless you explicitly want to flatten the directory structure, but never mind.
You're doing a lot to get the path to subdirectories: cd
into the directory, pwd
to a file and then read that file into a variable. Instead you could just use e.g. BUrout="$PWD/backup"
($PWD
holds the pathname of the current working directory).
You will never process any files because your loop is over the name of a directory. What you want is probably for i in "$r"/*; do
, and similarly in the second loop.
Always double quote your variable expansions! E.g. if [ "$i" = "$r" ]
(note also single =
, not double). See both "Why does my shell script choke on whitespace or other special characters?" and "Security implications of forgetting to quote a variable in bash/POSIX shells"
Your script should not need a single cd
. Scripts that steps into and out of directories are really hard to debug.
Apart from that, no syntax errors, and the logic seems to be correct.
May I suggest something like this, which is still using the same looping logic and mostly the same tests as your code is using, but without the calls to cd
and without having to fiddle too much with directory names:
#!/bin/sh
source="$1"
dest="$2"
mkdir -p "$dest" # creates destination directory if not already exists
for name in "$source"/*; do
if [ -f "$name" ]; then
cp "$name" "$dest"
elif [ -d "$name" ]; then
for name2 in "$name"/*; do
if [ -f "$name2" ]; then
cp "$name2" "$dest"
fi
done
fi
done
Or, using shortcut-syntax which seems to appeal to some people:
#!/bin/sh
source="$1"
dest="$2"
mkdir -p "$dest" # creates destination directory if not already exists
for name in "$source"/*; do
[ -f "$name" ] && { cp "$name" "$dest"; continue; }
[ ! -d "$name" ] && continue
for name2 in "$name"/*; do
[ -f "$name2" ] && cp "$name2" "$dest"
done
done
This script takes two arguments, the source directory and the target/destination directory:
$ ./script mydir some_new_backup_dir
No attempt is made to check whether any of the cp
commands would overwrite an existing file in the target directory.
Note also that both of these scripts are /bin/sh
script. They uses no things that are specific to the bash
shell.
Assuming that the target directory exists, this is more or less equivalent to
find source_dir -maxdepth 2 -type f -exec cp {} target_dir ';'