Eu não vejo isso documentado no manual do GNU Coreutils. É especificado por POSIX :
2. If source_file is of type directory, the following steps shall be taken:
[snip steps that don't apply in recursive mode when the target file is an existing directory]
f. The files in the directory source_file shall be copied to the directory dest_file […]
cp -rn
não ajuda porque a opção -n
apenas diz "não sobrescrever", mas a fusão de diretórios não sobregrava nada.
Não vejo nenhuma opção para rsync
ou pax
que possa ajudar você.
Você pode obter esse comportamento com um wrapper em torno de cp
. Analisar as opções da linha de comando é complicado. Código não testado. Problema conhecido: isso não suporta opções longas abreviadas.
function cp {
typeset source target=
typeset -a args sources
args=("$@") sources=()
while [[ $# -ne 0 ]]; do
case "$1" in
--target|-t) target=$2; shift args;;
--target=*) target=${1#*=};;
-t?*) target=${1#??};;
--no-preserve|--suffix|-S) shift;;
--) break;;
-|[^-]*) if [ -n "$POSIXLY_CORRECT" ]; then break; else sources+=($1); fi;;
esac
shift
done
sources+=("$@")
if [[ -z $target && ${#sources[@]} -ne 0 ]]; then
target=${sources[-1]}
unset sources[-1]
fi
for source in "${sources[@]}"; do
source=${source%"${source##*[^/]}"}
if [ -e "$target/${source##*/}" ]; then
echo >&2 "Refusing to copy $source to $target/${source##*/} because the target already exists"
return 1
fi
done
command cp "$@"
}