Regalamiunsorriso/sync/promote-file.sh

78 lines
No EOL
1.5 KiB
Bash

#!/bin/sh
set -eu
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
echo "usage: $0 <source> <destination> [metadata-source]" >&2
exit 64
fi
src="$1"
dst="$2"
metadata_source=${3:-}
dst_dir=$(dirname "$dst")
dst_name=$(basename "$dst")
dst_ext=""
case "$dst_name" in
*.*)
dst_ext=${dst_name##*.}
;;
esac
test -f "$src" || {
echo "source file not found: $src" >&2
exit 66
}
owner=""
group=""
mode=""
sample=""
if [ -e "$dst" ]; then
owner=$(stat -f '%Su' "$dst")
group=$(stat -f '%Sg' "$dst")
mode=$(stat -f '%Lp' "$dst")
else
if [ -n "$metadata_source" ]; then
test -e "$metadata_source" || {
echo "metadata source not found: $metadata_source" >&2
exit 66
}
sample=$metadata_source
elif [ -n "$dst_ext" ]; then
for candidate in "$dst_dir"/*."$dst_ext"; do
[ -e "$candidate" ] || continue
sample=$candidate
break
done
fi
if [ -z "$sample" ]; then
for candidate in "$dst_dir"/*; do
[ -f "$candidate" ] || continue
sample=$candidate
break
done
fi
if [ -n "$sample" ]; then
owner=$(stat -f '%Su' "$sample")
group=$(stat -f '%Sg' "$sample")
mode=$(stat -f '%Lp' "$sample")
else
owner=$(stat -f '%Su' "$dst_dir")
group=$(stat -f '%Sg' "$dst_dir")
mode=644
fi
fi
cp "$src" "$dst"
chown "$owner":"$group" "$dst"
chmod "$mode" "$dst"
printf 'copied %s -> %s\n' "$src" "$dst"
printf 'restored owner=%s group=%s mode=%s\n' "$owner" "$group" "$mode"
if [ -n "$sample" ]; then
printf 'metadata source=%s\n' "$sample"
fi