如何防止cp合并两个同名目录?

Emm*_*maV 7 cp merge

我有两个同名目录:

$ ls mydir
file1 file2

$ ls other/mydir
file3 file4
Run Code Online (Sandbox Code Playgroud)

如果我复制mydirother,则两者mydir合并:

$ cp -r mydir other

$ ls other/mydir
file1 file2 file3 file4
Run Code Online (Sandbox Code Playgroud)

在手册(或信息)页面中的cp哪个位置说它默认执行此操作?

如果我使用cp -rn mydir other.

如果cp问我是否要合并两个mydirs,我会更喜欢它;这样,如果我复制mydirother而忘记 中已经有不同mydirother,我可以中止操作。这可能吗?

Gil*_*il' 5

我在 GNU coreutils 手册中没有看到这一点。它由POSIX指定:

2. 如果source_file是directory 类型,则执行以下步骤:

[当目标文件是现有目录时,在递归模式下不适用的剪辑步骤]

    F。目录source_file中的文件应复制到目录dest_file […]

cp -rn没有帮助,因为该-n选项只说“不覆盖”,但合并目录不会覆盖任何内容。

我看不到任何选项rsyncpax可以帮助您。

您可以使用围绕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)