当我使用
cp -R inputFolder outputFolder
结果是依赖于上下文的:
- 如果
outputFolder
不存在则创建,克隆的文件夹路径为outputFolder
. - 如果
outputFolder
存在,那么创建的克隆将是outputFolder/inputFolder
这太可怕了,因为我想创建一些安装脚本,如果用户错误地运行它两次,他将outputFolder
创建第一次,然后在第二次运行时,所有内容将在 中再次创建outputFolder/inputFolder
。
- 我总是想要第一个行为:在原始对象旁边创建一个克隆(作为兄弟)。
- 我想用的
cp
是便携式的(例如MINGW没有rsync
发货) - 我检查过
cp -R --parents
,但这会重新创建目录树上的路径(因此克隆不会是outputFolder
但是some/path/outputFolder
) --remove-destination
或者--update
如果情况 2 不改变任何内容,仍然会将内容复制到outputFolder/inputFolder
有没有办法在不首先检查是否存在outputFolder
(如果文件夹不存在则...)或使用的情况下执行此操作rm -rf outputFolder
?
达成一致的、可移植的 UNIX 方法是什么?
答案1
使用这个代替:
cp -R inputFolder/. outputFolder
其工作方式与工作方式完全相同cp -R aaa/bbb ccc
:如果ccc
不存在,则将其创建为其bbb
内容的副本;但如果ccc
已经存在,则将ccc/bbb
创建为其bbb
内容的副本。
对于几乎任何bbb
这种情况,都会产生您在问题中指出的不良行为。然而,在这种特定情况下,“bbb
只是” .
, “aaa/bbb
真的”也是如此aaa/.
,而“真的”又是“真的只是” aaa
,但有另一个名字。所以我们有这两种情况:
ccc
不存在:该命令的
cp -R aaa/. ccc
意思是“创建并复制intoccc
的内容,即复制到.aaa/.
ccc/.
aaa
ccc
ccc
确实存在:该命令的
cp -R aaa/. ccc
意思是“将内容复制aaa/.
到ccc/.
,即复制aaa
到ccc
。
答案2
不要复制文件夹,只复制内容:
## Create the target directory. The -p suppresses error messages
## if the directory already exists
mkdir -p outputFolder
## Copy the contents recursively, this will not recreate the parent
cp -R inputfolder/* outputfolder/
这样,您既可以确保在脚本第一次运行时创建目标目录,又可以避免第二次运行时出现问题。
Chris Down 非常正确地指出,在 bash 中,这将跳过名称以.
.为了避免这种情况,您可以shopt -s dotglob
在运行上述命令之前运行。
答案3
尝试-T
选择cp
.这存在于 GNU coreutilscp
版本 8.22 中;在此之外它可能无法移植。
答案4
您可以使用命令-t
选项cp
:
cp -R inputFolder -t outputFolder
现在,如果目标文件夹不存在,则会抛出错误:
cp: failed to access ‘outputFolder’: No such file or directory
注意上面的命令将inputFolder
连同其内容一起复制(而不仅仅是其中的内容)
如果你只想复制inputFolder
它的内容会有点棘手(因为在使用星号 * 时使用 shell 通配符时必须小心)
cp -R -t outputFolder/ -- inputFolder/*
现在,如果目标文件夹不存在,则会抛出错误:
cp: failed to access ‘outputFolder’: No such file or directory
与cp (GNU coreutils) 8.23