O comportamento que você está procurando é um caso especial :
cp -R [-H|-L|-P] [-fip] source_file... target
[This] form is denoted by two or more operands where the -R option is specified. The cp utility shall copy each file in the file hierarchy rooted in each source_file to a destination path named as follows:
- If target exists and names an existing directory, the name of the corresponding destination path for each file in the file hierarchy shall be the concatenation of target, a single
<slash>
character if target did not end in a<slash>
, and the pathname of the file relative to the directory containing source_file.- If target does not exist and two operands are specified, the name of the corresponding destination path for source_file shall be target; the name of the corresponding destination path for all other files in the file hierarchy shall be the concatenation of target, a
<slash>
character, and the pathname of the file relative to source_file.It shall be an error if target does not exist and more than two operands are specified ...
Portanto, eu diria que não é possível fazer com que cp
faça o que você quer.
Como seu comportamento esperado é " cp -r dir1 dir2
(quando dir2
já existir) removerá o dir2
(e qualquer conteúdo) existente e o substituirá por dir1
":
rm -rf dir2 && cp -r dir1 dir2
Você nem precisa verificar se dir2
existe.
A solução rsync
estaria adicionando um /
à fonte para que não copiasse dir1
em dir2
, mas copiasse o conteúdo de dir1
para dir2
(ainda será manter arquivos existentes em dir2
):
$ tree dir*
dir1
└── test.txt
dir2
└── test2.txt
0 directories, 2 file
$ rsync -a dir1/ dir2
$ tree dir*
dir1
└── test.txt
dir2
└── test.txt
└── test2.txt
0 directories, 3 files
$ rm -r dir2
$ rsync -a dir1/ dir2
$ tree dir*
dir1
└── test.txt
dir2
└── test.txt
0 directories, 2 files