在终端(使用 bash 和 tcsh)中,如果文件夹参数末尾有 /,则 cp -r 将复制文件夹的内容而不是文件夹本身。
鉴于以下结构:
folderA
|-fileA
|-fileB
以下命令将文件 A 和文件 B 复制到目标,而不是将文件夹 A 复制到目标:
cp -r folderA/ destination
因此它充当
cp -r folderA/* destination
这非常烦人,因为默认情况下 tcsh 中的补全会在文件夹末尾添加一个 /,所以如果我忘记删除末尾的 /,我总是不得不清理。这种行为与我使用过的其他 *nix 不同。
有什么方法可以改变这种情况并让 cp -r folderA/ 复制文件夹而不是其内容?
答案1
有案例表明这种行为更有意义(我相信 rsync 也使用它,即使在 GNU/Linux 上也是如此)。考虑以下情况:
mydir
|-.fileA
|-fileB
这三个说明符的语义都是不同的:
cp -r mydir dest/ # creates dest/mydir, containing both files
cp -r mydir/ dest/ # copies both files directly into dest
cp -r mydir/* dest/ # copies fileB, but not .fileA, directly into dest
我相信这是 BSD 和 GNU 之间差异的一个例子。您可以使用以下方式安装 GNU 风格的工具芬克(看coreutils 包),但这些可能无法保留所有 HFS+ 元数据,因此请谨慎操作。
您可以截取命令并删除末尾的斜线。我将把这个留给读者或其他回答者作为练习。
您可以更改制表符补全行为,这样就不会首先添加斜线。将以下内容添加到您的~/.tcshrc
:
unset addsuffix
你可以在 bash 和其他 readline 实用程序中通过将以下内容添加到你的 来实现类似的效果~/.inputrc
:
set mark-directories off
答案2
无需手动删除默认安装中附加的“/”?不幸的是,苹果的 Darwin 上没有说明手册页cp 的意思是“如果源文件以 / 结尾,则复制目录的内容,而不是目录本身。”所以看起来这是达尔文设计的一部分cp
。
但是,可以取消设置addsuffix
shell 变量,tcsh
以便删除添加到目录中的“/”。最大的缺点是,现在很难仅从完成中判断您正在处理的是目录还是文件。为此,请在命令行中键入(或添加到 .tcshrc):
unset addsuffix
你bash
可以使用该mark-directories
设置。你可以输入以下内容或将其添加到你的 .bashrc 中:
bind 'set mark-directories off'
标记目录的使用来源:MacNN 论坛:Hal Itosis
答案3
“您可以拦截命令并删除尾部的斜杠。我将把这个留给读者或其他回答者作为练习。”添加
function cp() { /bin/cp $(echo "$*" | sed 's|/ | |g'); }
到 ~/.bashrc 似乎可以解决问题。