These two commands rcp
and rmv
acts a direct replacement for cp
and mv
for copying or moving files using rsync
.
Instead of doing:
rsync -avh --partial --info=progress2 source dest
rsync -avh --partial --info=progress2 --remove-source-files source dest
Now you can simply do:
rcp source dest
rmv source dest
You can also include additional rsync
options, here are two examples with -z
for compression (great for faster network transfers) and --dry-run
to see what gets transferred without actually transferring (yet).
rcp -z source dest
rmv --dry-run source dest
The rcp() and rmv() shell functions
You can copy and paste the following lines in your .zshrc
or .bashrc
file.
# Function to copy files using rsync
# Usage: rcp [rsync_options] source [source2...] destination
rcp() {
rsync -avh --partial --info=progress2 "$@"
}
# Function to move files using rsync (and delete empty directories after)
# Usage: rmv [rsync_options] source [source2...] destination
rmv() {
local default_options=(-avh --partial --info=progress2 --remove-source-files)
local rsync_options=()
local is_dry_run=0
# Separate options from paths
while [[ "$#" -gt 0 ]]; do
if [[ "$1" == "--dry-run" ]] || [[ "$1" == "-n" ]]; then
is_dry_run=1
rsync_options+=("$1")
elif [[ "$1" == "--" ]]; then
shift
break
elif [[ "$1" == "-"* ]]; then
rsync_options+=("$1")
else
break
fi
shift
done
# Check if at least two arguments remain (sources and destination)
if [[ "$#" -lt 2 ]]; then
echo "Usage: rmv [rsync_options] source [source2...] destination"
return 1
fi
local all_paths=("${@:1:$#}")
local source_paths=("${all_paths[@]:0:${#all_paths[@]}-1}")
local dest_path="${all_paths[-1]}"
# Execute rsync by passing options from the arrays
rsync "${default_options[@]}" "${rsync_options[@]}" "${source_paths[@]}" "$dest_path" && {
for source_dir in "${source_paths[@]}"; do
if [[ -d "$source_dir" ]]; then
if [[ $is_dry_run -eq 0 ]]; then
echo "Removing empty directory '$source_dir'..."
find "$source_dir" -type d -empty -delete
else
echo "Dry run: would remove empty directory '$source_dir'..."
find "$source_dir" -type d -empty -print
fi
fi
done
}
}
macOS users: Upgrade your rsync
The default rsync
tool that comes bundled with macOS is v2.6.9
does not support the --info=progress2
command, so run brew install rsync
to get the latest rsync.
$ /usr/bin/rsync --version
openrsync: protocol version 29
rsync version 2.6.9 compatible
$ /opt/homebrew/bin/rsync --version
rsync version 3.4.1 protocol version 32
Once installed, add this to your .zshrc
or .bashrc
file to replace the default rsync
with homebrew's rsync
.
alias rsync="/opt/homebrew/bin/rsync"
Handling the removal of empty directories
The --remove-source-files
option in rsync
does not remove empty directories after all the files has been moved. Therefore, in the rmv()
shell function above, you will notice that it will run additional commands to remove the empty directories using find
after rsync
has finished running.
So there you have it! These two little shell functions, rcp
and rmv
, wrapping up the power of rsync
into something as easy to use as cp
and mv
.
No more remembering long strings of options, just a simple command that gets the job done, with a nice progress update to boot.
Top comments (0)