-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpmv.sh
74 lines (61 loc) · 1.87 KB
/
cpmv.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env bash
#moving directories in the same filesystem does not copy data.
#It just changes a pointer.
#Sometimes this is not desirable, you need to copy data first
#and then delete the data.
#This is useful for btrfs/zfs when you change mount options (for example compress in btrfs)
#or move data across filesystems on the same tank (zfs)
#requirements bash version 4 or higher
#usage: cpmv source_directory target_directory
#target directory must not exist
src=$(readlink -e "$1")
#echo $src
srcbasename=$(basename "$src")
srcpath=$(dirname "$src")
#echo $srcbasename
#echo $srcpath
dirs=()
while IFS= read -d $'\0' -r file ; do
dir="${file:${#src}}"
#echo "$dir"
if [ "$dir" == "" ]; then
continue
fi
dirs+=("$dir")
done < <(find "$src" -depth -type d -print0)
files=()
while IFS= read -d $'\0' -r file ; do
files+=("$file")
done < <(find "$src" -type f -print0)
if [ ! -d "$2" ]; then
$(mkdir -p "$2")
#need a hash to store modification time of folders
declare -A dirmodtimes
#sore modification time of source
rootmodtime=$(stat -c %Y "$src")
for (( idx=${#dirs[@]}-1 ; idx>=0 ; idx-- )) ; do
$(mkdir "$2${dirs[idx]}")
#store the modification time of the directory
dirmodtimes[${dirs[idx]}]=$(stat -c %Y "$src${dirs[idx]}")
#echo ${dirs[idx]}
done
#for K in "${!dirmodtimes[@]}"; do echo $K --- ${dirmodtimes[$K]}; done
for file in "${files[@]}"
do
targetfile="${file:${#src}}"
$(cp -p "$file" "$2$targetfile")
$(rm "$file")
done
#restore permissions & modificaiton times of directories
for dir in "${dirs[@]}"
do
$(chown --reference="$src$dir" "$2$dir")
$(chmod --reference="$src$dir" "$2$dir")
$(touch -m -d "@${dirmodtimes[$dir]}" "$2$dir")
$(rmdir "$src$dir")
done
$(chown --reference="$src" "$2")
$(chmod --reference="$src" "$2")
$(touch -m -d "@$rootmodtime" "$2")
$(rmdir "$src")
fi