#!/bin/bash
set -eu -o pipefail -o noclobber
semi_atomic_cross_filesystem_copy () {
declare src="$1"
declare dst="$2"
declare dst_tmp="${dst}.part"
declare -i tmp_rc=
cat "$src" > "$dst_tmp" || tmp_rc=$?
if [[ $tmp_rc -ne 0 ]] ; then
return 2
elif [[ -e "$dst" ]] ; then
rm -v "$dst_tmp"
return 2
fi
mv -v "$dst_tmp" "$dst"
}
main () {
declare tgt_dir="/tmp/nicolaw/target_dir"
declare src_dir="/tmp/nicolaw/source_dir"
declare file
mkdir -pv "$tgt_dir" "$src_dir"
for file in {1..10} ; do
[[ -e "$src_dir/my$file.dat" ]] \
|| dd if=/dev/zero of="$src_dir/my$file.dat" count=1000000 bs=1024
done
for file in "$src_dir"/*.dat ; do
declare src="$file"
declare dst="$tgt_dir/${file##*/}"
if [[ -e "$dst" ]] ; then
echo "File $dst already exists."
else
declare -i copy_rc=
semi_atomic_cross_filesystem_copy "$src" "$dst" || copy_rc=$?
if [[ $copy_rc -eq 0 ]] ; then
echo "File $dst copied OK."
elif [[ $copy_rc -eq 2 ]] ; then
>&2 echo "Copy to $dst already in progress by another process."
else
>&2 echo "Copy to $dst failed."
fi
fi
done
}
main "$@"