Repository navigation
Expand file tree
/
Copy pathcp_p
More file actions
executable file
·162 lines (132 loc) · 4.57 KB
/
Copy pathcp_p
File metadata and controls
executable file
·162 lines (132 loc) · 4.57 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/bin/bash
## Bash settings
set -uo pipefail
## Script globals
script_name=$(basename "${BASH_SOURCE[0]}")
script_dir=$({ cd "$(dirname "${BASH_SOURCE[0]}")" || { echo "Failed to access script file directory" >&2; exit; } } && pwd)
script_dir_abs=$({ cd "$(dirname "${BASH_SOURCE[0]}")" || { echo "Failed to access script file directory" >&2; exit; } } && pwd -P)
script_file="${script_dir}/${script_name}"
if [ -L "${BASH_SOURCE[0]}" ]; then
script_file_abs=$(readlink "${BASH_SOURCE[0]}")
else
script_file_abs="${script_dir_abs}/${script_name}"
fi
export CURRENT_PARENT_BASH_SCRIPT_FILE="$script_file"
script_args=("$@")
## Script imports
lib_dir="${script_dir}/../lib"
bash_functions_script="${lib_dir}/bash_script_func.sh"
## Source imports
source "$bash_functions_script"
## Arguments
path_arg_arr=()
fwd_args_arr=()
dryrun=false
## Custom globals
target_dir_arg_provided=false
dst_dir=''
## Script usage
read -r -d '' script_usage << EOM
${script_name} ("cp --parents") Usage:
${script_name} [OPTION]... [-T] SOURCE DEST
${script_name} [OPTION]... SOURCE... DIRECTORY
${script_name} [OPTION]... -t DIRECTORY SOURCE...
(see 'man cp' for further details)
Copy file(s) with 'cp', first creating destination directory
with 'mkdir -p' if the destination directory does not exist.
Options:
[all 'cp' options]
EOM
if (( $# < 1 )); then
echo_e -e "$script_usage"
exit_script_with_status 1
fi
## Parse arguments
set +u
while (( $# > 0 )); do
arg="$1"
if [ "$(string_startswith "$arg" '-')" = false ]; then
path_arg_arr+=( "$arg" )
else
arg_opt="$(string_lstrip "$arg" '-')"
arg_opt_nargs=''
if [ "$(string_contains "$arg_opt" '=')" = true ]; then
arg_val=$(printf '%s' "${arg_opt#*=}" | sed -r -e "s|^['\"]+||" -e "s|['\"]+$||")
arg_opt="${arg_opt%%=*}"
arg_opt_raw="${arg%%=*}"
arg_opt_nargs_do_shift=false
else
arg_val="$2"
arg_opt_raw="$arg"
arg_opt_nargs_do_shift=true
fi
arg_val_can_start_with_dash=false
if [ "$arg_opt" = 'h' ] || [ "$arg_opt" = 'help' ]; then
arg_opt_nargs=0
echo "$script_usage"
exit 0
else
if [ "$(itemOneOf "$arg_opt" 't' 'target-directory' )" = true ]; then
target_dir_arg_provided=true
dst_dir="$arg_val"
fi
if [ "$(itemOneOf "$arg_opt" 'S' 'suffix' 't' 'target-directory' )" = true ]; then
arg_opt_nargs=1
if [ "$(string_contains "$arg_val" '*')" = true ] || [ "$(string_contains "$arg_val" ' ')" = true ]; then
arg_val="\"${arg_val}\""
fi
else
arg_opt_nargs=0
fi
fi
if [ -z "$arg_opt_nargs" ]; then
echo_e "Developer error! "'$arg_opt_nargs'" was not set for argument: ${arg}"
exit_script_with_status 1
fi
if [ "$arg_opt_nargs_do_shift" = true ] && (( arg_opt_nargs >= 1 )); then
for arg_num in $(seq 1 $arg_opt_nargs); do
shift
arg_val="$1"
if [ -z "$arg_val" ]; then
echo_e "Missing expected value (#${arg_num}) for argument: ${arg}"
exit_script_with_status 1
elif [ "$arg_val_can_start_with_dash" = false ] && [ "$(string_startswith "$arg_val" '-')" = true ]; then
echo_e "Unexpected argument value: ${arg} ${arg_val}"
exit_script_with_status 1
fi
done
fi
fi
shift
done
set -u
## Validate arguments
num_path_args="${#path_arg_arr[@]}"
if (( num_path_args == 0 )); then
# Allow 'cp' to report error
:
elif (( num_path_args == 1 )) || [ "$target_dir_arg_provided" = true ]; then
# Allow 'cp' to report error if target dir is not provided
:
else
dst_idx=$(( num_path_args - 1 ))
destination="${path_arg_arr[$dst_idx]}"
if (( num_path_args > 2 )) || [ "$(string_endswith "$destination" '/')" = true ]; then
dst_dir="$destination"
else
dst_dir=$(dirname "$destination")
fi
fi
## Create destination directory if needed
if [ -n "$dst_dir" ] && [ ! -d "$dst_dir" ]; then
mkdir -p "$dst_dir"
cmd_status=$?
if (( cmd_status != 0 )); then
echo_e "Received non-zero exit status (${cmd_status}) from mkdir command"
echo_e "mkdir -p ${dst_dir}"
echo_e "Exiting before copying file(s)"
exit_script_with_status 1
fi
fi
## Perform copying
cp "${script_args[@]}"