-
Notifications
You must be signed in to change notification settings - Fork 1
/
cpv.sh
executable file
·86 lines (72 loc) · 2.27 KB
/
cpv.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
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env bash
# cpv is a helper for copy files with pipe-viewer (pv) progress monitor
#
# Copyright 2016 diafour
# Source: http://github.com/diafour/pv-help-scripts
# This script is licensed under GPLv3; see LICENSE for details.
#
# Print usage and exit
function usage()
{
cat <<END_USAGE
Usage: `basename $0` SOURCE DEST
`basename $0` SOURCE DIRECTORY
`basename $0` SOURCE... DIRECTORY
Copy SOURCE file to DEST file or DEST directory, or multiple SOURCEs to DEST directory
with progress monitoring.
END_USAGE
exit
}
PVCMD="`which pv`"
#$PVCMD > /dev/null 2>&1
if [[ $? -ne 0 ]]
then
echo "Error: pv not installed or not in PATH"
echo
usage
fi
[ $# -lt 2 ] && usage
# DESTINATION
# Last parameter is destination like with cp command.
dest="${!#}"
# SOURCE is all other parameters
# Array of all parameters except last. Array used for proper handle of spaces in filenames.
src=("${@:1:($#-1)}")
# Calculate size of all sources
size=$(du -sbc "${src[@]}" | tail -n 1 | awk '{print $1}')
PVCMD="$PVCMD -s $size $PVOPTS"
if [[ $# -eq 2 && -d "${src[0]}" && -f "$dest" ]]
then
echo "Error: Copy SOURCE directory to DEST file is not supported"
echo
usage
fi
if [[ $# -eq 2 && -f "${src[0]}" && ( -f "$dest" || ! -e "$dest" ) ]]
then
# Copy SOURCE file to DEST file probably with new name
# cat is simpler than tar here
cat "${src[0]}" | $PVCMD > "${dest}"
elif [ -d "$dest" ]
then
# cp copy many source files without their pathes. Tar can do this with striping path from filenames using --xfrom/--transform.
# It works only for files. If src has directories then dest will be messed.
# tar --xform='s,.*/,,' --show-transformed -v -c -f ar.tar ../../test/a/1.png ../../test/a/aa/ad.jpg 1.png a
# tar -C dirname cf - basename - this works for directories.
# So loop over params and send tars to one pipe and untar with --ignore-zeros
{
for i in "${src[@]}"; do
if [ -f "$i" ]
then
tar --xform='s,.*/,,' -c -f - "$i" 2>/dev/null
fi
if [ -d "$i" ]
then
srcdir=`dirname "$i"`
srcname=`basename "$i"`
tar -C "$srcdir" -c -f - "$srcname"
fi
done
} | $PVCMD | tar --ignore-zeros -C "$dest" -x -f -
else
usage
fi