GNU cp和mv中-T选项的附加值是什么?


26

为什么某些GNU Coreutils命令可以-T/--no-target-directory选择?看起来它所做的所有事情都可以使用.传统Unix目录层次结构中(自我点)的语义来实现。

考虑:

cp -rT /this/source dir

-T选项可防止副本创建dir/source子目录。而是用/this/source标识,dir并且内容相应地映射在树之间。因此,例如/this/source/foo.cdir/foo.c等等,而不是去dir/source/foo.c

但这可以轻松实现,而无需-T使用以下选项:

cp -r /this/source/. dir  # Probably worked fine since dawn of Unix?

语义上,尾随点组件被复制为的子元素dir,但当然“子”已经存在(因此不必创建)并且实际上是dir其本身,因此其效果/this/path由标识dir

如果当前目录是目标目录,则可以正常工作:

cp -r /this/tree/node/. . # node's children go to current dir

有什么事你可以做的只能-T能合理化它的存在?(除了支持未实现点目录的操作系统外,文档中未提及的基本原理。)

上面的点技巧是否不能解决GNU Info文档中提到的相同竞争条件-T

Answers:


29

.当你复制一个目录,而不是文件把戏只能用。该-T选项适用于目录和文件。如果您这样做:

cp srcfile destfile

并且已经有一个名为destfile它将复制到的目录destfile/srcfile,这可能不是故意的。所以你用

cp -T srcfile destfile

并且您正确地得到错误:

cp: cannot overwrite directory `destfile' with non-directory

如果尝试使用该.方法,则该副本将永远无法工作:

cp: cannot stat `srcfile/.`: Not a directory

.确实复制文件时,在同一时间只是不重命名它的基本名称,当工作!cp /path/to/file /target/dir/. 如果/target/dir/file存在并且是目录,则将得到相同的诊断!但是,您已经展示了-T没有竞争条件就一步一步就能完成的工作:复制文件并更改文件名而不将其分流到子目录。
卡兹(Kaz)2013年

3
那是不一样的- .您正在谈论的技巧是附加/.源代码之后
Barmar

21

这个问题cp/ mv/ ln因为它们最初设计的是,他们两个命令在一个(拷贝复制到)。

cp A B

将A复制到B还是将A复制到B将A复制到B / A),具体取决于是否B存在并且是否为目录(如果B是指向目录的符号链接,则还有更多变化)。

不好是因为它含糊不清。因此,GNU实现添加了解决此问题的选项。

cp -T A B

份A到B不管。如果B存在并且是目录,那么它将失败(除非您通过-r)。无论如何,当您打算将其复制 B 时,都不会以A文件结尾。BA

和:

cp -t B A

复制到中


最初的unix理念是假设您知道自己的工作,并乐意让您自己射击。
Lenne

4
@Lenne,但是在这里它并没有给您避免脚部射击的方法。如果有人在运行cp A B命令之前创建了B目录或指向某个目录的符号链接,则该命令将无法实现您的预​​期。而且这样做[ -e B ] || [ -L B ] || cp A B仍然具有没有的竞争条件cp -Tn A B
斯特凡Chazelas

6

-T可以提供故障如果不正确的目录存在什么应该是一个目标文件:

$ mkdir mustbeafile
$ touch afile
$ cp -T afile mustbeafile
cp: cannot overwrite directory `mustbeafile' with non-directory
$ echo $?
1
$ cp afile mustbeafile
$ 

就是说,不是出现意外复制到子目录的成功,而是出现了警告和不正确的退出状态,这可能导致脚本中止,然后人工检查为什么有目录不应该存在成为一个。


0

当在脚本中使用命令而不是手动输入命令时,使用标志也更清楚,并且具有较小的意外影响风险。将点修补到脚本中的路径上可能会导致各种意外的恶作剧。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.