我有两个同名目录:
$ ls mydir
file1 file2
$ ls other/mydir
file3 file4
Run Code Online (Sandbox Code Playgroud)
如果我复制mydir
到other
,则两者mydir
合并:
$ cp -r mydir other
$ ls other/mydir
file1 file2 file3 file4
Run Code Online (Sandbox Code Playgroud)
在手册(或信息)页面中的cp
哪个位置说它默认执行此操作?
如果我使用cp -rn mydir other
.
如果cp
问我是否要合并两个mydir
s,我会更喜欢它;这样,如果我复制mydir
到other
而忘记 中已经有不同mydir
的other
,我可以中止操作。这可能吗?
我在 GNU coreutils 手册中没有看到这一点。它由POSIX指定:
2. 如果source_file是directory 类型,则执行以下步骤:
[当目标文件是现有目录时,在递归模式下不适用的剪辑步骤]
F。目录source_file中的文件应复制到目录dest_file […]
cp -rn
没有帮助,因为该-n
选项只说“不覆盖”,但合并目录不会覆盖任何内容。
我看不到任何选项rsync
或pax
可以帮助您。
您可以使用围绕cp
. 不过解析命令行选项很繁琐。未经测试的代码。已知问题:这不支持缩写的长选项。
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 "$@"
}
Run Code Online (Sandbox Code Playgroud)